Horizon
variant.hpp
Go to the documentation of this file.
1 // Range v3 library
3 //
4 // Copyright Eric Niebler 2014-present
5 //
6 // Use, modification and distribution is subject to the
7 // Boost Software License, Version 1.0. (See accompanying
8 // file LICENSE_1_0.txt or copy at
9 // http://www.boost.org/LICENSE_1_0.txt)
10 //
11 // Project home: https://github.com/ericniebler/range-v3
12 //
13 
14 #ifndef RANGES_V3_UTILITY_VARIANT_HPP
15 #define RANGES_V3_UTILITY_VARIANT_HPP
16 
19 #include <range/v3/detail/variant.hpp>
25 
26 #include <range/v3/detail/prologue.hpp>
27 
28 namespace ranges
29 {
31  namespace detail
32  {
33  template<typename T, std::size_t N, typename Index>
34  struct indexed_datum<T[N], Index>
35  {
36  private:
37  union
38  {
39  char c;
40  T data_[N];
41  };
42  void fill_default_(T * p, std::true_type)
43  {
44  for(; p != ranges::end(data_); ++p)
45  ::new((void *)p) T{};
46  }
47  void fill_default_(T * p, std::false_type)
48  {
49  RANGES_EXPECT(p == ranges::end(data_));
50  }
51 
52  public:
53  CPP_member
54  constexpr CPP_ctor(indexed_datum)(meta::nil_ = {})(
55  requires default_constructible<T>)
56  : data_{}
57  {}
58  CPP_member
59  CPP_ctor(indexed_datum)(indexed_datum && that)(
60  requires move_constructible<T>)
61  {
62  std::uninitialized_copy_n(make_move_iterator(that.data_), N, data_);
63  }
64  CPP_member
65  CPP_ctor(indexed_datum)(indexed_datum const & that)(
66  requires copy_constructible<T>)
67  {
68  std::uninitialized_copy_n(that.data_, N, data_);
69  }
70  // \pre Requires distance(first, last) <= N
71  // \pre Requires default_constructible<T> || distance(first, last) == N
72  template(typename I, typename S)(
73  requires sentinel_for<S, I> AND input_iterator<I> AND
74  constructible_from<T, iter_reference_t<I>>)
75  indexed_datum(I first, S last)
76  {
77  T * p = detail::uninitialized_copy(first, last, data_);
78  this->fill_default_(p, meta::bool_<default_constructible<T>>{});
79  }
80  // \pre Requires distance(r) <= N
81  // \pre Requires default_constructible<T> || distance(r) == N
82  template(typename R)(
83  requires input_range<R> AND constructible_from<T, range_reference_t<R>>)
84  explicit indexed_datum(R && r)
85  : indexed_datum{ranges::begin(r), ranges::end(r)}
86  {}
87  CPP_member
88  auto operator=(indexed_datum && that) //
89  -> CPP_ret(indexed_datum &)(
90  requires assignable_from<T &, T>)
91  {
92  ranges::move(that.data_, data_);
93  return *this;
94  }
95  CPP_member
96  auto operator=(indexed_datum const & that) //
97  -> CPP_ret(indexed_datum &)(
98  requires assignable_from<T &, T const &>)
99  {
100  ranges::copy(that.data_, data_);
101  return *this;
102  }
103  // \pre Requires ranges::distance(r) <= N
104  template(typename R)(
105  requires input_range<R> AND assignable_from<T &, range_reference_t<R>>)
106  indexed_datum & operator=(R && r)
107  {
108  ranges::copy(r, data_);
109  return *this;
110  }
111  constexpr auto ref()
112  {
113  return indexed_element<T(&)[N], Index::value>{data_};
114  }
115  constexpr auto ref() const
116  {
117  return indexed_element<T const(&)[N], Index::value>{data_};
118  }
119  constexpr T (&get() noexcept)[N]
120  {
121  return data_;
122  }
123  constexpr T const (&get() const noexcept)[N]
124  {
125  return data_;
126  }
127  };
128  } // namespace detail
130 } // namespace ranges
131 
132 #include <range/v3/detail/epilogue.hpp>
133 
134 #endif
std::integral_constant< bool, B > bool_
An integral constant wrapper for bool.
Definition: meta.hpp:168
front< Pair > first
Retrieve the first element of the pair Pair.
Definition: meta.hpp:2251
An empty type.
Definition: meta.hpp:135