...
This commit is contained in:
@@ -280,15 +280,15 @@ public:
|
||||
}
|
||||
|
||||
|
||||
// latitude and longitude
|
||||
template <mcc_angle_c LAT_T, mcc_angle_c LON_T>
|
||||
void geoPosition(std::pair<LAT_T, LON_T>* coords) const
|
||||
// longitude and latitude
|
||||
template <mcc_angle_c LON_T, mcc_angle_c LAT_T>
|
||||
void geoPosition(std::pair<LON_T, LAT_T>* coords) const
|
||||
{
|
||||
std::lock_guard lock{*_stateMutex};
|
||||
|
||||
if (coords) {
|
||||
coords->first = _currentState.lat;
|
||||
coords->second = _currentState.lon;
|
||||
coords->first = _currentState.lon;
|
||||
coords->second = _currentState.lat;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -473,11 +473,11 @@ struct mcc_skypoint_interface_t {
|
||||
return std::forward<SelfT>(self).refractInverseCorrection(dZ);
|
||||
}
|
||||
|
||||
// returns apparent sideral time (Greenwich) for the epoch of the celestial point
|
||||
// returns apparent sideral time (Greenwich or local) for the epoch of the celestial point
|
||||
template <std::derived_from<mcc_skypoint_interface_t> SelfT>
|
||||
auto appSideralTime(this SelfT&& self, mcc_angle_c auto* st)
|
||||
auto appSideralTime(this SelfT&& self, mcc_angle_c auto* st, bool is_local)
|
||||
{
|
||||
return std::forward<SelfT>(self).appSideralTime(st);
|
||||
return std::forward<SelfT>(self).appSideralTime(st, is_local);
|
||||
}
|
||||
|
||||
// returns equation of origins for the epoch of the celestial point
|
||||
@@ -571,7 +571,7 @@ concept mcc_pcm_c = std::derived_from<T, mcc_pcm_interface_t<typename T::error_t
|
||||
// static constexpr uint16_t HW_MOVE_ERROR = 555;
|
||||
// }
|
||||
template <typename T>
|
||||
concept mcc_hardware_movement_state_c = requires {
|
||||
concept mcc_hardware_movement_state_c = std::formattable<T, char> && requires {
|
||||
[]() {
|
||||
// // mount axes were stopped
|
||||
// [[maybe_unused]] static constexpr auto v0 = T::HW_MOVE_STOPPED;
|
||||
@@ -621,7 +621,6 @@ concept mcc_hardware_movement_state_c = requires {
|
||||
template <typename T>
|
||||
concept mcc_hardware_state_c = requires(T state) {
|
||||
// encoder co-longitude and co-latiitude positions, as well as its measurement time point
|
||||
// the given constrains on coordinate pair kind can be used to deduce mount type
|
||||
requires mcc_coord_pair_c<decltype(state.XY)> &&
|
||||
(decltype(state.XY)::pairKind == impl::MccCoordPairKind::COORDS_KIND_GENERIC ||
|
||||
decltype(state.XY)::pairKind == impl::MccCoordPairKind::COORDS_KIND_XY);
|
||||
|
||||
@@ -475,7 +475,7 @@ public:
|
||||
std::pair<double, double> pos;
|
||||
cctEngine.geoPosition(&pos);
|
||||
|
||||
return MccGeoLONLAT(pos.second, pos.first);
|
||||
return MccGeoLONLAT(pos.first, pos.second);
|
||||
}
|
||||
|
||||
|
||||
@@ -581,10 +581,9 @@ public:
|
||||
}
|
||||
|
||||
|
||||
error_t appSideralTime(mcc_angle_c auto* st) const
|
||||
error_t appSideralTime(mcc_angle_c auto* st, bool is_local = false) const
|
||||
{
|
||||
// return Greenwich apparent sideral time since epoch is UTC
|
||||
return cctEngine.apparentSideralTime(_epoch, st, false);
|
||||
return cctEngine.apparentSideralTime(_epoch, st, is_local);
|
||||
}
|
||||
|
||||
|
||||
@@ -735,6 +734,16 @@ protected:
|
||||
static_assert(PT::pairKind != MccCoordPairKind::COORDS_KIND_UNKNOWN, "UNSUPPORTED SKY POINT TRANSFORMATION!");
|
||||
|
||||
|
||||
if constexpr (PT::pairKind == MccCoordPairKind::COORDS_KIND_LONLAT) { // returns geographic site coordinates
|
||||
std::pair<double, double> pos;
|
||||
cctEngine.geoPosition(&pos);
|
||||
|
||||
cpair.setX(pos.first);
|
||||
cpair.setY(pos.second);
|
||||
|
||||
return error_t{};
|
||||
}
|
||||
|
||||
if (_pairKind == MccCoordPairKind::COORDS_KIND_RADEC_ICRS &&
|
||||
PT::pairKind == MccCoordPairKind::COORDS_KIND_RADEC_ICRS) { // from ICRS to ICRS - just copy and exit
|
||||
cpair = PT(typename PT::x_t(_x), typename PT::y_t(_y));
|
||||
|
||||
277
mcc_ser.h
277
mcc_ser.h
@@ -158,8 +158,10 @@ template <typename VT>
|
||||
struct MccSerializer : MccSerializerBase {
|
||||
constexpr static std::string_view serializerName{"MCC-FALLBACK-SERIALIZER"};
|
||||
|
||||
template <typename ParamsT = std::nullptr_t>
|
||||
error_t operator()(traits::mcc_output_char_range auto& output, VT const& value, ParamsT const& params = nullptr)
|
||||
template <typename ParamsT = mcc_serialization_params_t>
|
||||
error_t operator()(traits::mcc_output_char_range auto& output,
|
||||
VT const& value,
|
||||
ParamsT const& params = mcc_serialization_params_t{})
|
||||
{
|
||||
if constexpr (std::formattable<VT, char>) {
|
||||
} else if constexpr (std::convertible_to<VT, std::string>) {
|
||||
@@ -205,8 +207,10 @@ struct MccSerializer<VT> : MccSerializerBase {
|
||||
|
||||
constexpr static std::string_view serializerName{"MCC-SYSTIME-SERIALIZER"};
|
||||
|
||||
template <typename ParamsT = std::nullptr_t>
|
||||
error_t operator()(traits::mcc_output_char_range auto& output, VT const& value, ParamsT const& params = nullptr)
|
||||
template <typename ParamsT = mcc_serialization_params_t>
|
||||
error_t operator()(traits::mcc_output_char_range auto& output,
|
||||
VT const& value,
|
||||
ParamsT const& params = mcc_serialization_params_t{})
|
||||
{
|
||||
std::vformat_to(std::back_inserter(output), params.systime_format, std::make_format_args(value));
|
||||
|
||||
@@ -220,8 +224,10 @@ template <typename VT>
|
||||
struct MccSerializer<VT> : MccSerializerBase {
|
||||
constexpr static std::string_view serializerName{"MCC-ANGLE-SERIALIZER"};
|
||||
|
||||
template <typename ParamsT = std::nullptr_t>
|
||||
error_t operator()(traits::mcc_output_char_range auto& output, VT const& value, ParamsT const& params = nullptr)
|
||||
template <typename ParamsT = mcc_serialization_params_t>
|
||||
error_t operator()(traits::mcc_output_char_range auto& output,
|
||||
VT const& value,
|
||||
ParamsT const& params = mcc_serialization_params_t{})
|
||||
{
|
||||
double v = (double)value; // radians (see mcc_angle_c concept)
|
||||
std::string sgm;
|
||||
@@ -264,8 +270,10 @@ template <mcc_coord_epoch_c VT>
|
||||
struct MccSerializer<VT> : MccSerializerBase {
|
||||
constexpr static std::string_view serializerName{"MCC-COORD-EPOCH-SERIALIZER"};
|
||||
|
||||
template <typename ParamsT = std::nullptr_t>
|
||||
error_t operator()(traits::mcc_output_char_range auto& output, VT const& value, ParamsT const& params = nullptr)
|
||||
template <typename ParamsT = mcc_serialization_params_t>
|
||||
error_t operator()(traits::mcc_output_char_range auto& output,
|
||||
VT const& value,
|
||||
ParamsT const& params = mcc_serialization_params_t{})
|
||||
{
|
||||
double jd;
|
||||
|
||||
@@ -304,11 +312,12 @@ template <mcc_coord_pair_c VT>
|
||||
struct MccSerializer<VT> : MccSerializerBase {
|
||||
constexpr static std::string_view serializerName{"MCC-COORD-PAIR-SERIALIZER"};
|
||||
|
||||
template <typename ParamsT = std::nullptr_t>
|
||||
error_t operator()(traits::mcc_output_char_range auto& output, VT const& value, ParamsT const& params = nullptr)
|
||||
template <typename ParamsT = mcc_serialization_params_t>
|
||||
error_t operator()(traits::mcc_output_char_range auto& output,
|
||||
VT const& value,
|
||||
ParamsT const& params = mcc_serialization_params_t{})
|
||||
{
|
||||
std::conditional_t<std::is_null_pointer_v<ParamsT>, std::nullptr_t, mcc_serialization_params_t> pars =
|
||||
std::is_null_pointer_v<ParamsT> ? nullptr : params;
|
||||
auto pars = params;
|
||||
|
||||
pars.norm_sxgm = true;
|
||||
pars.coordpair_format = MccSerializedCoordPairFormat::MCC_SERIALIZED_FORMAT_SXGM_HOURDEG;
|
||||
@@ -358,8 +367,10 @@ template <mcc_skypoint_c VT>
|
||||
struct MccSerializer<VT> : MccSerializerBase {
|
||||
constexpr static std::string_view serializerName{"MCC-SKYPOINT-SERIALIZER"};
|
||||
|
||||
template <typename ParamsT = std::nullptr_t>
|
||||
error_t operator()(traits::mcc_output_char_range auto& output, VT const& value, ParamsT const& params = nullptr)
|
||||
template <typename ParamsT = mcc_serialization_params_t>
|
||||
error_t operator()(traits::mcc_output_char_range auto& output,
|
||||
VT const& value,
|
||||
ParamsT const& params = mcc_serialization_params_t{})
|
||||
{
|
||||
auto serialize_cpair = [&]<typename T>(T& cp) {
|
||||
auto ccte_err = value.to(cp);
|
||||
@@ -423,52 +434,256 @@ template <mcc_telemetry_data_c VT>
|
||||
struct MccSerializer<VT> : MccSerializerBase {
|
||||
constexpr static std::string_view serializerName{"MCC-TELEMETRY-DATA-SERIALIZER"};
|
||||
|
||||
template <typename ParamsT = std::nullptr_t>
|
||||
error_t operator()(traits::mcc_output_char_range auto& output, VT const& value, ParamsT const& params = nullptr)
|
||||
template <typename ParamsT = mcc_serialization_params_t>
|
||||
error_t operator()(traits::mcc_output_char_range auto& output,
|
||||
VT const& value,
|
||||
ParamsT const& params = mcc_serialization_params_t{})
|
||||
{
|
||||
// FORMAT: RA_OBS_MOUNT, DEC_OBS_MOUNT, RA_APP_MOUNT, DEC_APP_MOUNT, HA_APP_MOUNT, AZ_MOUNT, ZD_MOUNT,
|
||||
// REFR_CORR_MOUNT, LAST, ENC_X, ENC_Y, PCM_X, PCM_Y, RA_APP_TAG, DEC_APP_TAG, AZ_TAG, ZD_TAG, TIMEPOINT
|
||||
// REFR_CORR_MOUNT, ENC_X, ENC_Y, PCM_X, PCM_Y, RA_APP_TAG, DEC_APP_TAG, AZ_TAG, ZD_TAG, LAST, EO, TIMEPOINT,
|
||||
// STATUS
|
||||
|
||||
// NOTE: One must assume that the returned RA coordinates are in format of underlying celestial coordinate
|
||||
// transformation engine used in the mcc_skypoint_c class implementation. E.g. ERFA-library uses the
|
||||
// CIO-based representation of RA
|
||||
|
||||
std::conditional_t<std::is_null_pointer_v<ParamsT>, std::nullptr_t, mcc_serialization_params_t> pars =
|
||||
std::is_null_pointer_v<ParamsT> ? nullptr : params;
|
||||
auto pars_h = params;
|
||||
|
||||
pars.norm_sxgm = true;
|
||||
pars.coordpair_format = MccSerializedCoordPairFormat::MCC_SERIALIZED_FORMAT_SXGM_HOURDEG;
|
||||
auto pars_d = params;
|
||||
|
||||
std::string ra_obs, ra_app, ha, last, ra_app_tg;
|
||||
MccSkyRADEC_OBS r_obs;
|
||||
MccSkyRADEC_APP r_app;
|
||||
|
||||
pars_h.norm_sxgm = true;
|
||||
pars_h.coordpair_format = MccSerializedCoordPairFormat::MCC_SERIALIZED_FORMAT_SXGM_HOURDEG;
|
||||
pars_d.norm_sxgm = true;
|
||||
pars_d.coordpair_format = MccSerializedCoordPairFormat::MCC_SERIALIZED_FORMAT_SXGM_HOURDEG;
|
||||
|
||||
MccSkyRADEC_OBS rd_obs;
|
||||
MccSkyRADEC_APP rd_app;
|
||||
MccSkyHADEC_APP hd_app;
|
||||
MccSkyAZZD azzd;
|
||||
|
||||
// quantities in hour representation
|
||||
MccSerializerBase::angleFormatFromCoordPairType<VT::pairKind, MccSerializerBase::CO_LON>(pars);
|
||||
MccSerializerBase::angleFormatFromCoordPairType<VT::pairKind, MccSerializerBase::CO_LON>(pars_h);
|
||||
|
||||
// quantities in degree representation
|
||||
MccSerializerBase::angleFormatFromCoordPairType<VT::pairKind, MccSerializerBase::CO_LON>(pars_d);
|
||||
|
||||
MccSerializer<MccAngle> ang_sr;
|
||||
|
||||
// RA_OBS_MOUNT
|
||||
auto ccte_err = value.mountPos.toAtSameEpoch(r_obs);
|
||||
// RA_OBS_MOUNT, DEC_OBS_MOUNT
|
||||
auto ccte_err = value.mountPos.toAtSameEpoch(rd_obs);
|
||||
if (ccte_err) {
|
||||
return mcc_deduced_err(ccte_err, MccSerializerErrorCode::ERROR_COORD_TRANSFORM);
|
||||
}
|
||||
|
||||
auto err = ang_sr(ra_obs, r_obs, pars);
|
||||
auto err = ang_sr(output, rd_obs.x(), pars_h);
|
||||
if (err) {
|
||||
return mcc_deduced_err(err, MccSerializerErrorCode::ERROR_UNDERLYING_SERIALIZER);
|
||||
}
|
||||
|
||||
// RA_APP_MOUNT
|
||||
ccte_err = value.mountPos.toAtSameEpoch(r_app);
|
||||
MccSerializerBase::addElemDelimiter(output, pars_h);
|
||||
|
||||
err = ang_sr(output, rd_obs.y(), pars_h);
|
||||
if (err) {
|
||||
return mcc_deduced_err(err, MccSerializerErrorCode::ERROR_UNDERLYING_SERIALIZER);
|
||||
}
|
||||
|
||||
MccSerializerBase::addElemDelimiter(output, pars_h);
|
||||
|
||||
// RA_APP_MOUNT, DEC_APP_MOUNT
|
||||
ccte_err = value.mountPos.toAtSameEpoch(rd_app);
|
||||
if (ccte_err) {
|
||||
return mcc_deduced_err(ccte_err, MccSerializerErrorCode::ERROR_COORD_TRANSFORM);
|
||||
}
|
||||
|
||||
err = ang_sr(ra_app, r_app, pars);
|
||||
err = ang_sr(output, rd_app.x(), pars_h);
|
||||
if (err) {
|
||||
return mcc_deduced_err(err, MccSerializerErrorCode::ERROR_UNDERLYING_SERIALIZER);
|
||||
}
|
||||
|
||||
MccSerializerBase::addElemDelimiter(output, pars_h);
|
||||
|
||||
err = ang_sr(output, rd_app.y(), pars_d);
|
||||
if (err) {
|
||||
return mcc_deduced_err(err, MccSerializerErrorCode::ERROR_UNDERLYING_SERIALIZER);
|
||||
}
|
||||
|
||||
MccSerializerBase::addElemDelimiter(output, pars_h);
|
||||
|
||||
// HA_APP_MOUNT
|
||||
ccte_err = value.mountPos.toAtSameEpoch(hd_app);
|
||||
if (ccte_err) {
|
||||
return mcc_deduced_err(ccte_err, MccSerializerErrorCode::ERROR_COORD_TRANSFORM);
|
||||
}
|
||||
|
||||
err = ang_sr(output, hd_app.x(), pars_h);
|
||||
if (err) {
|
||||
return mcc_deduced_err(err, MccSerializerErrorCode::ERROR_UNDERLYING_SERIALIZER);
|
||||
}
|
||||
|
||||
|
||||
MccSerializerBase::addElemDelimiter(output, pars_h);
|
||||
|
||||
// AZ_MOUNT, ZD_MOUNT
|
||||
ccte_err = value.mountPos.toAtSameEpoch(azzd);
|
||||
if (ccte_err) {
|
||||
return mcc_deduced_err(ccte_err, MccSerializerErrorCode::ERROR_COORD_TRANSFORM);
|
||||
}
|
||||
|
||||
err = ang_sr(output, azzd.x(), pars_d);
|
||||
if (err) {
|
||||
return mcc_deduced_err(err, MccSerializerErrorCode::ERROR_UNDERLYING_SERIALIZER);
|
||||
}
|
||||
|
||||
MccSerializerBase::addElemDelimiter(output, pars_h);
|
||||
|
||||
err = ang_sr(output, azzd.y(), pars_d);
|
||||
if (err) {
|
||||
return mcc_deduced_err(err, MccSerializerErrorCode::ERROR_UNDERLYING_SERIALIZER);
|
||||
}
|
||||
|
||||
MccSerializerBase::addElemDelimiter(output, pars_h);
|
||||
|
||||
// refraction correction
|
||||
|
||||
MccAngle ang;
|
||||
ccte_err = value.mountPos.refractCorrection(&ang);
|
||||
if (ccte_err) {
|
||||
return mcc_deduced_err(ccte_err, MccSerializerErrorCode::ERROR_COORD_TRANSFORM);
|
||||
}
|
||||
|
||||
err = ang_sr(output, ang, pars_d);
|
||||
if (err) {
|
||||
return mcc_deduced_err(err, MccSerializerErrorCode::ERROR_UNDERLYING_SERIALIZER);
|
||||
}
|
||||
|
||||
MccSerializerBase::addElemDelimiter(output, pars_h);
|
||||
|
||||
|
||||
// encoder X and Y
|
||||
|
||||
err = ang_sr(output, value.hwState.XY.x(), pars_d);
|
||||
if (err) {
|
||||
return mcc_deduced_err(err, MccSerializerErrorCode::ERROR_UNDERLYING_SERIALIZER);
|
||||
}
|
||||
|
||||
MccSerializerBase::addElemDelimiter(output, pars_h);
|
||||
|
||||
err = ang_sr(output, value.hwState.XY.y(), pars_d);
|
||||
if (err) {
|
||||
return mcc_deduced_err(err, MccSerializerErrorCode::ERROR_UNDERLYING_SERIALIZER);
|
||||
}
|
||||
|
||||
MccSerializerBase::addElemDelimiter(output, pars_h);
|
||||
|
||||
|
||||
// PCM X and Y
|
||||
|
||||
err = ang_sr(output, value.pcmCorrection.pcmX(), pars_d);
|
||||
if (err) {
|
||||
return mcc_deduced_err(err, MccSerializerErrorCode::ERROR_UNDERLYING_SERIALIZER);
|
||||
}
|
||||
|
||||
MccSerializerBase::addElemDelimiter(output, pars_h);
|
||||
|
||||
err = ang_sr(output, value.pcmCorrection.pcmY(), pars_d);
|
||||
if (err) {
|
||||
return mcc_deduced_err(err, MccSerializerErrorCode::ERROR_UNDERLYING_SERIALIZER);
|
||||
}
|
||||
|
||||
MccSerializerBase::addElemDelimiter(output, pars_h);
|
||||
|
||||
|
||||
// RA_APP_TAG, DEC_APP_TAG
|
||||
ccte_err = value.targetPos.toAtSameEpoch(rd_app);
|
||||
if (ccte_err) {
|
||||
return mcc_deduced_err(ccte_err, MccSerializerErrorCode::ERROR_COORD_TRANSFORM);
|
||||
}
|
||||
|
||||
err = ang_sr(output, rd_app.x(), pars_h);
|
||||
if (err) {
|
||||
return mcc_deduced_err(err, MccSerializerErrorCode::ERROR_UNDERLYING_SERIALIZER);
|
||||
}
|
||||
|
||||
MccSerializerBase::addElemDelimiter(output, pars_h);
|
||||
|
||||
err = ang_sr(output, rd_app.y(), pars_d);
|
||||
if (err) {
|
||||
return mcc_deduced_err(err, MccSerializerErrorCode::ERROR_UNDERLYING_SERIALIZER);
|
||||
}
|
||||
|
||||
MccSerializerBase::addElemDelimiter(output, pars_h);
|
||||
|
||||
// AZ_TAG, ZD_TAG
|
||||
ccte_err = value.targetPos.toAtSameEpoch(azzd);
|
||||
if (ccte_err) {
|
||||
return mcc_deduced_err(ccte_err, MccSerializerErrorCode::ERROR_COORD_TRANSFORM);
|
||||
}
|
||||
|
||||
err = ang_sr(output, azzd.x(), pars_d);
|
||||
if (err) {
|
||||
return mcc_deduced_err(err, MccSerializerErrorCode::ERROR_UNDERLYING_SERIALIZER);
|
||||
}
|
||||
|
||||
MccSerializerBase::addElemDelimiter(output, pars_h);
|
||||
|
||||
err = ang_sr(output, azzd.y(), pars_d);
|
||||
if (err) {
|
||||
return mcc_deduced_err(err, MccSerializerErrorCode::ERROR_UNDERLYING_SERIALIZER);
|
||||
}
|
||||
|
||||
MccSerializerBase::addElemDelimiter(output, pars_h);
|
||||
|
||||
|
||||
// LAST, local apparent sideral time
|
||||
|
||||
ccte_err = value.mountPos.appSideralTime(&ang, true);
|
||||
if (ccte_err) {
|
||||
return mcc_deduced_err(ccte_err, MccSerializerErrorCode::ERROR_COORD_TRANSFORM);
|
||||
}
|
||||
|
||||
err = ang_sr(output, ang, pars_h);
|
||||
if (err) {
|
||||
return mcc_deduced_err(err, MccSerializerErrorCode::ERROR_UNDERLYING_SERIALIZER);
|
||||
}
|
||||
|
||||
MccSerializerBase::addElemDelimiter(output, pars_h);
|
||||
|
||||
|
||||
// EO, equation of origins
|
||||
|
||||
ccte_err = value.mountPos.EO(&ang);
|
||||
if (ccte_err) {
|
||||
return mcc_deduced_err(ccte_err, MccSerializerErrorCode::ERROR_COORD_TRANSFORM);
|
||||
}
|
||||
|
||||
err = ang_sr(output, ang, pars_h);
|
||||
if (err) {
|
||||
return mcc_deduced_err(err, MccSerializerErrorCode::ERROR_UNDERLYING_SERIALIZER);
|
||||
}
|
||||
|
||||
MccSerializerBase::addElemDelimiter(output, pars_h);
|
||||
|
||||
// coordinates epoch
|
||||
|
||||
auto ep_err = MccSerializer<MccCelestialCoordEpoch>{}(output, value.mountPos.epoch(), pars_d);
|
||||
if (ep_err) {
|
||||
return mcc_deduced_err(err, MccSerializerErrorCode::ERROR_UNDERLYING_SERIALIZER);
|
||||
}
|
||||
|
||||
MccSerializerBase::addElemDelimiter(output, pars_h);
|
||||
|
||||
|
||||
// status (it must be formattable, see mcc_concepts.h)
|
||||
|
||||
auto st_err =
|
||||
MccSerializer<decltype(value.hwState.movementState)>{}(output, value.hwState.movementState, pars_d);
|
||||
if (st_err) {
|
||||
return mcc_deduced_err(err, MccSerializerErrorCode::ERROR_UNDERLYING_SERIALIZER);
|
||||
}
|
||||
|
||||
|
||||
return MccSerializerErrorCode::ERROR_OK;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -163,7 +163,7 @@ static constexpr std::string_view MCC_SERIALIZING_DEFAULT_ELEM_DELIMITER{","};
|
||||
|
||||
|
||||
template <typename T>
|
||||
concept mcc_serialization_params_c = requires(T t) {
|
||||
concept mcc_serialization_params_c = std::copyable<T> && requires(T t) {
|
||||
requires traits::mcc_output_char_range<decltype(t.seq_delim)>;
|
||||
requires traits::mcc_output_char_range<decltype(t.elem_delim)>;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user