• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2020-2021 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
15 template <class Rep, class Period>
16 class bogus_duration {
17 public:
18     bogus_duration() = default;
19 
20     template <class T>
bogus_duration(const T & val,typename std::enable_if<std::is_convertible<T,Rep>::value>::type * =nullptr)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>
bogus_duration(const bogus_duration<Rep2,Period2> & val,typename std::enable_if<std::is_convertible<Period2,Rep>::value>::type * =nullptr)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 
get_rep() const34     Rep get_rep() const { return rep_; }
35 
36 private:
37     Rep rep_{0};
38 };
39 
40 struct struct_with_bogus_duration {
41     std::optional<bogus_duration<long, char>> d0;
42     std::optional<bogus_duration<long, char>> d1;
43 };
44 
45 struct 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 
main()54 int main() {
55     struct_with_optional val{
56         std::chrono::seconds{1},
57         std::chrono::seconds{2},
58         std::chrono::seconds{3},
59         std::chrono::seconds{4},
60         std::chrono::seconds{5},
61         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{bogus_duration<long, char>{1}, 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