#include "mcc_angle.h" #include "mcc_defaults.h" #include "mcc_generics.h" namespace mcc { template class MccCoordPair { public: typedef CO_LON_T x_t; typedef CO_LAT_T y_t; static constexpr MccCoordPairKind pairKind = !(std::derived_from || std::derived_from) // unknown type (possibly just double or float) ? MccCoordPairKind::COORDS_KIND_GENERIC : (std::same_as || std::same_as) // one of the types is MccAngle ? MccCoordPairKind::COORDS_KIND_GENERIC // ICRS RA and DEC : (std::same_as && std::same_as) ? MccCoordPairKind::COORDS_KIND_RADEC_ICRS // apparent RA and DEC : (std::same_as && std::same_as) ? MccCoordPairKind::COORDS_KIND_RADEC_APP // observed RA and DEC : (std::same_as && std::same_as) ? MccCoordPairKind::COORDS_KIND_RADEC_APP // apparent HA and DEC : (std::same_as && std::same_as) ? MccCoordPairKind::COORDS_KIND_HADEC_APP // observed HA and DEC : (std::same_as && std::same_as) ? MccCoordPairKind::COORDS_KIND_HADEC_APP // apparent AZ and ZD : (std::same_as && std::same_as) ? MccCoordPairKind::COORDS_KIND_AZZD // apparent AZ and ALT : (std::same_as && std::same_as) ? MccCoordPairKind::COORDS_KIND_AZZD // general purpose X and Y : (std::same_as && std::same_as) ? MccCoordPairKind::COORDS_KIND_XY // geographical longitude and latitude : (std::same_as && std::same_as) ? MccCoordPairKind::COORDS_KIND_LONLAT : MccCoordPairKind::COORDS_KIND_UNKNOWN; template MccCoordPair(CO_LON_T const& x, CO_LAT_T const& y, EpT const& epoch = EpT::now()) : _x(x), _y(y), _mjd(epoch.MJD) { } MccCoordPair(const MccCoordPair&) = default; MccCoordPair(MccCoordPair&&) = default; MccCoordPair& operator=(const MccCoordPair&) = default; MccCoordPair& operator=(MccCoordPair&&) = default; virtual ~MccCoordPair() = default; CO_LON_T x() const { return _x; } CO_LAT_T y() const { return _y; } double MJD() const { return _mjd; } // for something like: // auto [ra, dec, mjd] = coord_pair; operator std::tuple() const { return {_x, _y, _mjd}; } void setX(const CO_LON_T& x) { _x = x; } void setY(const CO_LAT_T& y) { _y = y; } void setMJD(double mjd) { _mjd = mjd; } protected: CO_LON_T _x; CO_LAT_T _y; double _mjd; }; template concept mcc_coord_pair_c = requires { typename T::x_t; typename T::y_t; requires std::derived_from>; }; /* predefined coordinate pairs */ template requires(std::derived_from && std::derived_from) class MccNamedCoordPair : public MccCoordPair { public: template requires(std::is_arithmetic_v && std::is_arithmetic_v) MccNamedCoordPair(CxT const& x, CyT const& y, EpT const& epoch = EpT::now()) : MccCoordPair(CO_LON_T{x}, CO_LAT_T{y}, epoch) { } template MccNamedCoordPair(MccAngle const& x, MccAngle const& y, EpT const& epoch = EpT::now()) : MccCoordPair(CO_LON_T{(double)x}, CO_LAT_T{(double)y}, epoch) { } MccNamedCoordPair(const MccNamedCoordPair&) = default; MccNamedCoordPair(MccNamedCoordPair&&) = default; MccNamedCoordPair& operator=(const MccNamedCoordPair&) = default; MccNamedCoordPair& operator=(MccNamedCoordPair&&) = default; virtual ~MccNamedCoordPair() = default; }; using MccSkyRADEC_ICRS = MccNamedCoordPair; using MccSkyRADEC_APP = MccNamedCoordPair; using MccSkyRADEC_OBS = MccNamedCoordPair; using MccSkyHADEC_APP = MccNamedCoordPair; using MccSkyHADEC_OBS = MccNamedCoordPair; using MccSkyAZZD = MccNamedCoordPair; using MccSkyAZALT = MccNamedCoordPair; using MccGenXY = MccNamedCoordPair; using MccGeoLONLAT = MccNamedCoordPair; struct mcc_skycoord_interface_t { virtual ~mcc_skycoord_interface_t() = default; template SelfT, mcc_angle_c XT, mcc_angle_c YT> SelfT& from(this SelfT&& self, XT&& x, YT&& y) { return std::forward(self).from(std::forward(x), std::forward(y)); } template SelfT, mcc_coord_pair_c PT> SelfT& from(this SelfT&& self, PT&& cpair) { return std::forward(self).from(std::forward(cpair)); } template SelfT, mcc_coord_pair_c PT> SelfT& operator=(this SelfT&& self, PT&& cpair) { return std::forward(self).operator=(std::forward(cpair)); } template SelfT, mcc_coord_pair_c PT, mcc_coord_pair_c... PTs> SelfT& to(this SelfT&& self, PT& cpair, PTs&... cpairs) { return std::forward(self).to(cpair, cpairs...); } template SelfT, mcc_coord_pair_c PT> operator PT(this SelfT&& self) { return std::forward(self).operator PT(); } template SelfT, mcc_coord_pair_c PT, mcc_coord_pair_c... PTs> operator std::tuple(this SelfT&& self) { return std::forward(self).operator std::tuple(); } }; template concept mcc_skycoord_c = std::derived_from && requires(T t) { typename T::meteo_t; { T::meteo(std::declval()) }; }; class MccSkyPoint : public mcc_skycoord_interface_t { public: }; } // end namespace mcc