/// \file // Range v3 library // // Copyright Eric Niebler 2014-present // // Use, modification and distribution is subject to the // Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Project home: https://github.com/ericniebler/range-v3 // #ifndef RANGES_V3_UTILITY_VARIANT_HPP #define RANGES_V3_UTILITY_VARIANT_HPP #include #include #include #include #include #include #include #include namespace ranges { /// \cond namespace detail { template struct indexed_datum { private: union { char c; T data_[N]; }; void fill_default_(T * p, std::true_type) { for(; p != ranges::end(data_); ++p) ::new((void *)p) T{}; } void fill_default_(T * p, std::false_type) { RANGES_EXPECT(p == ranges::end(data_)); } public: CPP_member constexpr CPP_ctor(indexed_datum)(meta::nil_ = {})( requires default_constructible) : data_{} {} CPP_member CPP_ctor(indexed_datum)(indexed_datum && that)(requires move_constructible) { std::uninitialized_copy_n(make_move_iterator(that.data_), N, data_); } CPP_member CPP_ctor(indexed_datum)(indexed_datum const & that)( requires copy_constructible) { std::uninitialized_copy_n(that.data_, N, data_); } // \pre Requires distance(first, last) <= N // \pre Requires default_constructible || distance(first, last) == N template CPP_ctor(indexed_datum)(I first, S last)( // requires sentinel_for && input_iterator && constructible_from>) { T * p = detail::uninitialized_copy(first, last, data_); this->fill_default_(p, meta::bool_>{}); } // \pre Requires distance(r) <= N // \pre Requires default_constructible || distance(r) == N template explicit CPP_ctor(indexed_datum)(R && r)( // requires input_range && constructible_from>) : indexed_datum{ranges::begin(r), ranges::end(r)} {} CPP_member auto operator=(indexed_datum && that) -> CPP_ret(indexed_datum &)( // requires assignable_from) { ranges::move(that.data_, data_); return *this; } CPP_member auto operator=(indexed_datum const & that) -> CPP_ret(indexed_datum &)( // requires assignable_from) { ranges::copy(that.data_, data_); return *this; } // \pre Requires ranges::distance(r) <= N template auto operator=(R && r) -> CPP_ret(indexed_datum &)( // requires input_range && assignable_from>) { ranges::copy(r, data_); return *this; } constexpr indexed_element ref() { return {data_}; } constexpr indexed_element ref() const { return {data_}; } constexpr T (&get() noexcept)[N] { return data_; } constexpr T const (&get() const noexcept)[N] { return data_; } }; } // namespace detail /// \endcond } // namespace ranges #endif