1// Copyright (c) 2020-2024 Antony Polukhin
2//
3// Distributed under the Boost Software License, Version 1.0. (See accompanying
4// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5
6#include <boost/core/lightweight_test.hpp>
7
8#include <boost/pfr/core.hpp>
9
10#include <chrono>
11
12#include <optional>
13
14// This class mimics libc++ implementation of std::chrono::duration with unfxed LWG3050
15template <class Rep, class Period>
16class bogus_duration {
17public:
18 bogus_duration() = default;
19
20 template <class T>
21 explicit bogus_duration(const T& val,
22 typename std::enable_if<
23 std::is_convertible<T, Rep>::value // <= libstdc++ fix for LWG3050 is 's/T/const T&/g'
24 >::type* = nullptr)
25 : rep_(val)
26 {}
27
28 template <class Rep2, class Period2>
29 bogus_duration(const bogus_duration<Rep2, Period2>& val,
30 typename std::enable_if<std::is_convertible<Period2, Rep>::value>::type* = nullptr)
31 : rep_(val)
32 {}
33
34 Rep get_rep() const { return rep_; }
35
36private:
37 Rep rep_{0};
38};
39
40struct struct_with_bogus_duration {
41 std::optional<bogus_duration<long, char>> d0;
42 std::optional<bogus_duration<long, char>> d1;
43};
44
45struct struct_with_optional {
46 std::optional<std::chrono::seconds> a;
47 std::optional<std::chrono::milliseconds> b;
48 std::optional<std::chrono::microseconds> c;
49 std::optional<std::chrono::nanoseconds> d;
50 std::optional<std::chrono::steady_clock::duration> e;
51 std::optional<std::chrono::system_clock::duration> f;
52};
53
54int main() {
55 struct_with_optional val{
56 .a: std::chrono::seconds{1},
57 .b: std::chrono::seconds{2},
58 .c: std::chrono::seconds{3},
59 .d: std::chrono::seconds{4},
60 .e: std::chrono::seconds{5},
61 .f: std::chrono::seconds{6},
62 };
63
64 using boost::pfr::get;
65 BOOST_TEST(get<0>(val) == std::chrono::seconds{1});
66 BOOST_TEST(get<1>(val) == std::chrono::seconds{2});
67 BOOST_TEST(get<2>(val) == std::chrono::seconds{3});
68 BOOST_TEST(get<3>(val) == std::chrono::seconds{4});
69 BOOST_TEST(get<3>(val) > std::chrono::seconds{0});
70 BOOST_TEST(get<3>(val) > std::chrono::seconds{0});
71
72 struct_with_bogus_duration val2{.d0: bogus_duration<long, char>{1}, .d1: bogus_duration<long, char>{2}};
73 BOOST_TEST(get<0>(val2)->get_rep() == 1);
74 BOOST_TEST(get<1>(val2)->get_rep() == 2);
75
76 return boost::report_errors();
77}
78
79

source code of boost/libs/pfr/test/core/run/optional_chrono.cpp