tempoch-cpp 0.5.5
Header-only C++ wrapper for tempoch
Loading...
Searching...
No Matches
period.hpp
Go to the documentation of this file.
1#pragma once
2
8#include "qtty/qtty.hpp"
9#include "time.hpp"
10#include <ostream>
11#include <vector>
12
13namespace tempoch {
14
15template <typename S> struct TimeTraits<Time<S>> {
16 static double to_mjd_value(const Time<S> &time) {
17 return time.template to<format::MJD>().value();
18 }
19
23};
24
25template <typename S, typename F> struct TimeTraits<EncodedTime<S, F>> {
26 static double to_mjd_value(const EncodedTime<S, F> &time) {
27 if constexpr (std::is_same_v<F, format::MJD>) {
28 return time.value();
29 } else {
30 return Time<S>::from_encoded(time).template to<format::MJD>().value();
31 }
32 }
33
35 if constexpr (std::is_same_v<F, format::MJD>) {
36 return EncodedTime<S, F>(mjd);
37 } else {
38 return ModifiedJulianDate<S>(mjd).template to<F>();
39 }
40 }
41};
42
43template <> struct TimeTraits<CivilTime> {
44 static double to_mjd_value(const CivilTime &time) {
45 return Time<scale::UTC>::from_civil(time).template to<format::MJD>().value();
46 }
47
51};
52
53namespace detail {
54
55template <typename Target, typename T> auto convert_period_endpoint(const T &value) {
56 if constexpr (std::is_same_v<std::decay_t<T>, CivilTime>) {
57 return Time<scale::UTC>::from_civil(value).template to<Target>();
58 } else {
59 return value.template to<Target>();
60 }
61}
62
63template <typename TargetA, typename TargetB, typename T>
64auto convert_period_endpoint(const T &value) {
65 if constexpr (std::is_same_v<std::decay_t<T>, CivilTime>) {
67 } else {
68 return value.template to<TargetA, TargetB>();
69 }
70}
71
72template <typename Target, typename T>
73auto convert_period_endpoint_with(const T &value, const TimeContext &ctx) {
74 if constexpr (std::is_same_v<std::decay_t<T>, CivilTime>) {
75 return Time<scale::UTC>::from_civil(value, ctx).template to_with<Target>(ctx);
76 } else {
77 return value.template to_with<Target>(ctx);
78 }
79}
80
81template <typename TargetA, typename TargetB, typename T>
82auto convert_period_endpoint_with(const T &value, const TimeContext &ctx) {
83 if constexpr (std::is_same_v<std::decay_t<T>, CivilTime>) {
85 } else {
86 return value.template to_with<TargetA, TargetB>(ctx);
87 }
88}
89
90} // namespace detail
91
92template <typename T = ModifiedJulianDate<scale::TT>> class Period {
94
95 explicit Period(const tempoch_period_mjd_t &inner) : m_inner(inner) {}
96
97public:
102 Period(const T &start, const T &end) {
105 "Period::Period");
106 }
107
108 static Period from_c(const tempoch_period_mjd_t &c) { return Period(c); }
109
110 T start() const { return TimeTraits<T>::from_mjd_value(m_inner.start_mjd); }
111 T end() const { return TimeTraits<T>::from_mjd_value(m_inner.end_mjd); }
112
113 template <typename Target> auto to() const {
114 auto converted_start = detail::convert_period_endpoint<Target>(start());
115 auto converted_end = detail::convert_period_endpoint<Target>(end());
116 using OutT = std::decay_t<decltype(converted_start)>;
118 }
119
120 template <typename TargetA, typename TargetB> auto to() const {
121 auto converted_start = detail::convert_period_endpoint<TargetA, TargetB>(start());
122 auto converted_end = detail::convert_period_endpoint<TargetA, TargetB>(end());
123 using OutT = std::decay_t<decltype(converted_start)>;
125 }
126
127 template <typename Target> auto to_with(const TimeContext &ctx) const {
128 auto converted_start = detail::convert_period_endpoint_with<Target>(start(), ctx);
129 auto converted_end = detail::convert_period_endpoint_with<Target>(end(), ctx);
130 using OutT = std::decay_t<decltype(converted_start)>;
132 }
133
134 template <typename TargetA, typename TargetB> auto to_with(const TimeContext &ctx) const {
135 auto converted_start = detail::convert_period_endpoint_with<TargetA, TargetB>(start(), ctx);
136 auto converted_end = detail::convert_period_endpoint_with<TargetA, TargetB>(end(), ctx);
137 using OutT = std::decay_t<decltype(converted_start)>;
139 }
140
141 template <typename TargetType = qtty::DayTag>
142 qtty::Quantity<typename qtty::ExtractTag<TargetType>::type> duration() const {
143 auto qty = tempoch_period_mjd_duration_qty(m_inner);
144 return qtty::Quantity<qtty::DayTag>(qty.value).template to<TargetType>();
145 }
146
148 template <typename TargetType = qtty::DayTag>
149 qtty::Quantity<typename qtty::ExtractTag<TargetType>::type> length() const {
150 return duration<TargetType>();
151 }
152
156 "Period::intersection");
157 return from_c(out);
158 }
159
160 bool contains(const T &point) const noexcept {
162 }
163
164 std::vector<Period<T>> union_with(const Period<T> &other) const {
166 std::size_t count = 0;
168 "Period::union_with");
169 std::vector<Period<T>> result;
170 result.reserve(count);
171 for (std::size_t i = 0; i < count; ++i)
172 result.push_back(from_c(buf[i]));
173 return result;
174 }
175
176 std::vector<Period<T>> complement_of(const std::vector<Period<T>> &others) const {
177 std::vector<tempoch_period_mjd_t> raw;
178 raw.reserve(others.size());
179 for (const auto &p : others)
180 raw.push_back(p.c_inner());
181 tempoch_period_mjd_t *out = nullptr;
182 std::size_t n = 0;
183 check_status(tempoch_period_list_complement(m_inner, raw.data(), raw.size(), &out, &n),
184 "Period::complement_of");
185 std::vector<Period<T>> result;
186 result.reserve(n);
187 for (std::size_t i = 0; i < n; ++i)
188 result.push_back(from_c(out[i]));
190 return result;
191 }
192
193 const tempoch_period_mjd_t &c_inner() const noexcept { return m_inner; }
194};
195
196template <typename T> Period(T, T) -> Period<T>;
197
200
201namespace detail {
202
203template <typename T>
204inline std::vector<tempoch_period_mjd_t> to_raw(const std::vector<Period<T>> &periods) {
205 std::vector<tempoch_period_mjd_t> raw;
206 raw.reserve(periods.size());
207 for (const auto &p : periods)
208 raw.push_back(p.c_inner());
209 return raw;
210}
211
212template <typename T>
213inline std::vector<Period<T>> from_alloc(tempoch_period_mjd_t *ptr, std::size_t count) {
214 std::vector<Period<T>> result;
215 result.reserve(count);
216 for (std::size_t i = 0; i < count; ++i)
217 result.push_back(Period<T>::from_c(ptr[i]));
219 return result;
220}
221
222} // namespace detail
223
224template <typename T> inline void validate_periods(const std::vector<Period<T>> &periods) {
225 auto raw = detail::to_raw(periods);
226 check_status(tempoch_period_list_validate(raw.data(), raw.size()), "validate_periods");
227}
228
229template <typename T>
230inline std::vector<Period<T>> intersect_periods(const std::vector<Period<T>> &a,
231 const std::vector<Period<T>> &b) {
232 auto ra = detail::to_raw(a), rb = detail::to_raw(b);
233 tempoch_period_mjd_t *out = nullptr;
234 std::size_t n = 0;
235 check_status(tempoch_period_list_intersect(ra.data(), ra.size(), rb.data(), rb.size(), &out, &n),
236 "intersect_periods");
237 return detail::from_alloc<T>(out, n);
238}
239
240template <typename T>
241inline std::vector<Period<T>> union_periods(const std::vector<Period<T>> &a,
242 const std::vector<Period<T>> &b) {
243 auto ra = detail::to_raw(a), rb = detail::to_raw(b);
244 tempoch_period_mjd_t *out = nullptr;
245 std::size_t n = 0;
246 check_status(tempoch_period_list_union(ra.data(), ra.size(), rb.data(), rb.size(), &out, &n),
247 "union_periods");
248 return detail::from_alloc<T>(out, n);
249}
250
251template <typename T>
252inline std::vector<Period<T>> normalize_periods(const std::vector<Period<T>> &periods) {
253 auto raw = detail::to_raw(periods);
254 tempoch_period_mjd_t *out = nullptr;
255 std::size_t n = 0;
256 check_status(tempoch_period_list_normalize(raw.data(), raw.size(), &out, &n),
257 "normalize_periods");
258 return detail::from_alloc<T>(out, n);
259}
260
261template <typename T> inline std::ostream &operator<<(std::ostream &os, const Period<T> &period) {
262 return os << '[' << period.start() << ", " << period.end() << ')';
263}
264
265} // namespace tempoch
A typed external encoding of a time instant on scale S.
auto to() const
Definition period.hpp:113
qtty::Quantity< typename qtty::ExtractTag< TargetType >::type > duration() const
Definition period.hpp:142
const tempoch_period_mjd_t & c_inner() const noexcept
Definition period.hpp:193
Period intersection(const Period &other) const
Definition period.hpp:153
auto to() const
Definition period.hpp:120
bool contains(const T &point) const noexcept
Definition period.hpp:160
T start() const
Definition period.hpp:110
auto to_with(const TimeContext &ctx) const
Definition period.hpp:134
Period(const T &start, const T &end)
Definition period.hpp:102
auto to_with(const TimeContext &ctx) const
Definition period.hpp:127
std::vector< Period< T > > union_with(const Period< T > &other) const
Definition period.hpp:164
static Period from_c(const tempoch_period_mjd_t &c)
Definition period.hpp:108
std::vector< Period< T > > complement_of(const std::vector< Period< T > > &others) const
Definition period.hpp:176
T end() const
Definition period.hpp:111
qtty::Quantity< typename qtty::ExtractTag< TargetType >::type > length() const
Returns the length of the period (primary name; duration() is a backward-compat alias).
Definition period.hpp:149
Immutable conversion context for UT1 and historical UTC routes.
A point in time on scale S, stored as a split J2000-second pair.
static Time from_civil(const CivilTime &civil)
static Time from_encoded(const EncodedTime< S, Fmt > &encoded)
Decode a scalar encoding Fmt into canonical split storage on scale S (default context).
CivilTime to_civil() const
std::vector< tempoch_period_mjd_t > to_raw(const std::vector< Period< T > > &periods)
Definition period.hpp:204
auto convert_period_endpoint_with(const T &value, const TimeContext &ctx)
Definition period.hpp:73
std::vector< Period< T > > from_alloc(tempoch_period_mjd_t *ptr, std::size_t count)
Definition period.hpp:213
auto convert_period_endpoint(const T &value)
Definition period.hpp:55
std::ostream & operator<<(std::ostream &os, const CivilTime &u)
Stream CivilTime as YYYY-MM-DD HH:MM:SS[.nnnnnnnnn].
std::vector< Period< T > > intersect_periods(const std::vector< Period< T > > &a, const std::vector< Period< T > > &b)
Definition period.hpp:230
std::vector< Period< T > > normalize_periods(const std::vector< Period< T > > &periods)
Definition period.hpp:252
void validate_periods(const std::vector< Period< T > > &periods)
Definition period.hpp:224
void check_status(tempoch_status_t status, const char *operation)
Check a tempoch_status_t and throw the appropriate exception on error.
Definition ffi_core.hpp:139
std::vector< Period< T > > union_periods(const std::vector< Period< T > > &a, const std::vector< Period< T > > &b)
Definition period.hpp:241
constexpr tempoch_scale_tag_t scale_tag_v
UTC date-time breakdown.
static CivilTime from_mjd_value(double mjd)
Definition period.hpp:48
static double to_mjd_value(const CivilTime &time)
Definition period.hpp:44
static double to_mjd_value(const EncodedTime< S, F > &time)
Definition period.hpp:26
static EncodedTime< S, F > from_mjd_value(double mjd)
Definition period.hpp:34
static Time< S > from_mjd_value(double mjd)
Definition period.hpp:20
static double to_mjd_value(const Time< S > &time)
Definition period.hpp:16
Public aliases for tempoch time encodings.