You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

126 line
4.2KB

  1. /// \file
  2. // 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. #ifndef RANGES_V3_UTILITY_VARIANT_HPP
  14. #define RANGES_V3_UTILITY_VARIANT_HPP
  15. #include <range/v3/algorithm/copy.hpp>
  16. #include <range/v3/algorithm/move.hpp>
  17. #include <range/v3/detail/variant.hpp>
  18. #include <range/v3/iterator/move_iterators.hpp>
  19. #include <range/v3/iterator/operations.hpp>
  20. #include <range/v3/range/access.hpp>
  21. #include <range/v3/range/concepts.hpp>
  22. #include <range/v3/range/primitives.hpp>
  23. namespace ranges
  24. {
  25. /// \cond
  26. namespace detail
  27. {
  28. template<typename T, std::size_t N, typename Index>
  29. struct indexed_datum<T[N], Index>
  30. {
  31. private:
  32. union
  33. {
  34. char c;
  35. T data_[N];
  36. };
  37. void fill_default_(T * p, std::true_type)
  38. {
  39. for(; p != ranges::end(data_); ++p)
  40. ::new((void *)p) T{};
  41. }
  42. void fill_default_(T * p, std::false_type)
  43. {
  44. RANGES_EXPECT(p == ranges::end(data_));
  45. }
  46. public:
  47. CPP_member
  48. constexpr CPP_ctor(indexed_datum)(meta::nil_ = {})(
  49. requires default_constructible<T>)
  50. : data_{}
  51. {}
  52. CPP_member
  53. CPP_ctor(indexed_datum)(indexed_datum && that)(requires move_constructible<T>)
  54. {
  55. std::uninitialized_copy_n(make_move_iterator(that.data_), N, data_);
  56. }
  57. CPP_member
  58. CPP_ctor(indexed_datum)(indexed_datum const & that)(
  59. requires copy_constructible<T>)
  60. {
  61. std::uninitialized_copy_n(that.data_, N, data_);
  62. }
  63. // \pre Requires distance(first, last) <= N
  64. // \pre Requires default_constructible<T> || distance(first, last) == N
  65. template<typename I, typename S>
  66. CPP_ctor(indexed_datum)(I first, S last)( //
  67. requires sentinel_for<S, I> && input_iterator<I> &&
  68. constructible_from<T, iter_reference_t<I>>)
  69. {
  70. T * p = detail::uninitialized_copy(first, last, data_);
  71. this->fill_default_(p, meta::bool_<default_constructible<T>>{});
  72. }
  73. // \pre Requires distance(r) <= N
  74. // \pre Requires default_constructible<T> || distance(r) == N
  75. template<typename R>
  76. explicit CPP_ctor(indexed_datum)(R && r)( //
  77. requires input_range<R> && constructible_from<T, range_reference_t<R>>)
  78. : indexed_datum{ranges::begin(r), ranges::end(r)}
  79. {}
  80. CPP_member
  81. auto operator=(indexed_datum && that) -> CPP_ret(indexed_datum &)( //
  82. requires assignable_from<T &, T>)
  83. {
  84. ranges::move(that.data_, data_);
  85. return *this;
  86. }
  87. CPP_member
  88. auto operator=(indexed_datum const & that) -> CPP_ret(indexed_datum &)( //
  89. requires assignable_from<T &, T const &>)
  90. {
  91. ranges::copy(that.data_, data_);
  92. return *this;
  93. }
  94. // \pre Requires ranges::distance(r) <= N
  95. template<typename R>
  96. auto operator=(R && r) -> CPP_ret(indexed_datum &)( //
  97. requires input_range<R> && assignable_from<T &, range_reference_t<R>>)
  98. {
  99. ranges::copy(r, data_);
  100. return *this;
  101. }
  102. constexpr indexed_element<T[N], Index::value> ref()
  103. {
  104. return {data_};
  105. }
  106. constexpr indexed_element<T const [N], Index::value> ref() const {
  107. return {data_};
  108. } constexpr T (&get() noexcept)[N]
  109. {
  110. return data_;
  111. }
  112. constexpr T const (&get() const noexcept)[N]
  113. {
  114. return data_;
  115. }
  116. };
  117. } // namespace detail
  118. /// \endcond
  119. } // namespace ranges
  120. #endif