| 
							- /// \file
 - // Range v3 library
 - //
 - //  Copyright Eric Niebler 2013-present
 - //  Copyright Casey Carter 2016
 - //
 - //  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_BOX_HPP
 - #define RANGES_V3_UTILITY_BOX_HPP
 - 
 - #include <cstdlib>
 - #include <type_traits>
 - #include <utility>
 - 
 - #include <meta/meta.hpp>
 - 
 - #include <concepts/concepts.hpp>
 - 
 - #include <range/v3/range_fwd.hpp>
 - 
 - #include <range/v3/utility/get.hpp>
 - 
 - RANGES_DIAGNOSTIC_PUSH
 - RANGES_DIAGNOSTIC_IGNORE_DEPRECATED_DECLARATIONS
 - 
 - namespace ranges
 - {
 -     /// \addtogroup group-utility Utility
 -     /// @{
 -     ///
 - 
 -     /// \cond
 -     template<typename T>
 -     struct RANGES_DEPRECATED("The ranges::mutable_ class template is deprecated") mutable_
 -     {
 -         mutable T value;
 - 
 -         CPP_member
 -         constexpr CPP_ctor(mutable_)()( //
 -             requires std::is_default_constructible<T>::value)
 -           : value{}
 -         {}
 -         constexpr explicit mutable_(T const & t)
 -           : value(t)
 -         {}
 -         constexpr explicit mutable_(T && t)
 -           : value(detail::move(t))
 -         {}
 -         mutable_ const & operator=(T const & t) const
 -         {
 -             value = t;
 -             return *this;
 -         }
 -         mutable_ const & operator=(T && t) const
 -         {
 -             value = detail::move(t);
 -             return *this;
 -         }
 -         constexpr operator T &() const &
 -         {
 -             return value;
 -         }
 -     };
 - 
 -     template<typename T, T v>
 -     struct RANGES_DEPRECATED("The ranges::constant class template is deprecated") constant
 -     {
 -         constant() = default;
 -         constexpr explicit constant(T const &)
 -         {}
 -         constant & operator=(T const &)
 -         {
 -             return *this;
 -         }
 -         constant const & operator=(T const &) const
 -         {
 -             return *this;
 -         }
 -         constexpr operator T() const
 -         {
 -             return v;
 -         }
 -         constexpr T exchange(T const &) const
 -         {
 -             return v;
 -         }
 -     };
 -     /// \endcond
 - 
 -     /// \cond
 -     namespace detail
 -     {
 -         // "box" has three different implementations that store a T differently:
 -         enum class box_compress
 -         {
 -             none, // Nothing special: get() returns a reference to a T member subobject
 -             ebo,  // Apply Empty Base Optimization: get() returns a reference to a T base
 -                   // subobject
 -             coalesce // Coalesce all Ts into one T: get() returns a reference to a static
 -                      // T singleton
 -         };
 - 
 -         // Per N4582, lambda closures are *not*:
 -         // - aggregates             ([expr.prim.lambda]/4)
 -         // - default constructible_from  ([expr.prim.lambda]/p21)
 -         // - copy assignable        ([expr.prim.lambda]/p21)
 -         template<typename Fn>
 -         using could_be_lambda = meta::bool_<!std::is_default_constructible<Fn>::value &&
 -                                             !std::is_copy_assignable<Fn>::value>;
 - 
 -         template<typename>
 -         constexpr box_compress box_compression_(...)
 -         {
 -             return box_compress::none;
 -         }
 -         template<typename T, typename = meta::if_<meta::strict_and<
 -                                  std::is_empty<T>,
 -                                  meta::not_<detail::is_final<T>>
 - #if defined(__GNUC__) && !defined(__clang__) && __GNUC__ == 6 && __GNUC_MINOR__ < 2
 -                                  // GCC 6.0 & 6.1 find empty lambdas' implicit conversion
 -                                  // to function pointer when doing overload resolution
 -                                  // for function calls. That causes hard errors.
 -                                  // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71117
 -                                  ,
 -                                  meta::not_<could_be_lambda<T>>
 - #endif
 -                                  >>>
 -         constexpr box_compress box_compression_(long)
 -         {
 -             return box_compress::ebo;
 -         }
 - #ifndef RANGES_WORKAROUND_MSVC_249830
 -         // MSVC pukes passing non-constant-expression objects to constexpr
 -         // functions, so do not coalesce.
 -         template<typename T,
 -                  typename =
 -                      meta::if_<meta::strict_and<std::is_empty<T>, detail::is_trivial<T>>>>
 -         constexpr box_compress box_compression_(int)
 -         {
 -             return box_compress::coalesce;
 -         }
 - #endif
 -         template<typename T>
 -         constexpr box_compress box_compression()
 -         {
 -             return box_compression_<T>(0);
 -         }
 -     } // namespace detail
 -     /// \endcond
 - 
 -     template<typename Element, typename Tag = void,
 -              detail::box_compress = detail::box_compression<Element>()>
 -     class box
 -     {
 -         Element value;
 - 
 -     public:
 -         CPP_member
 -         constexpr CPP_ctor(box)()(                                          //
 -             noexcept(std::is_nothrow_default_constructible<Element>::value) //
 -             requires std::is_default_constructible<Element>::value)
 -           : value{}
 -         {}
 -         template<typename E>
 -         constexpr CPP_ctor(box)(E && e)(                               //
 -             noexcept(std::is_nothrow_constructible<Element, E>::value) //
 -             requires(!defer::same_as<box, detail::decay_t<E>>) &&
 -             defer::constructible_from<Element, E> && defer::convertible_to<E, Element>)
 -           : value(static_cast<E &&>(e))
 -         {}
 -         template<typename E>
 -         constexpr explicit CPP_ctor(box)(E && e)(                      //
 -             noexcept(std::is_nothrow_constructible<Element, E>::value) //
 -             requires(!defer::same_as<box, detail::decay_t<E>>) &&
 -             defer::constructible_from<Element, E> && (!defer::convertible_to<E, Element>))
 -           : value(static_cast<E &&>(e))
 -         {}
 - 
 -         constexpr Element & get() & noexcept
 -         {
 -             return value;
 -         }
 -         constexpr Element const & get() const & noexcept
 -         {
 -             return value;
 -         }
 -         constexpr Element && get() && noexcept
 -         {
 -             return detail::move(value);
 -         }
 -         constexpr Element const && get() const && noexcept
 -         {
 -             return detail::move(value);
 -         }
 -     };
 - 
 -     template<typename Element, typename Tag>
 -     class box<Element, Tag, detail::box_compress::ebo> : Element
 -     {
 -     public:
 -         CPP_member
 -         constexpr CPP_ctor(box)()(                                          //
 -             noexcept(std::is_nothrow_default_constructible<Element>::value) //
 -             requires std::is_default_constructible<Element>::value)
 -           : Element{}
 -         {}
 -         template<typename E>
 -         constexpr CPP_ctor(box)(E && e)(                               //
 -             noexcept(std::is_nothrow_constructible<Element, E>::value) //
 -             requires(!defer::same_as<box, detail::decay_t<E>>) &&
 -             defer::constructible_from<Element, E> && defer::convertible_to<E, Element>)
 -           : Element(static_cast<E &&>(e))
 -         {}
 -         template<typename E>
 -         constexpr explicit CPP_ctor(box)(E && e)(                      //
 -             noexcept(std::is_nothrow_constructible<Element, E>::value) //
 -             requires(!defer::same_as<box, detail::decay_t<E>>) &&
 -             defer::constructible_from<Element, E> && (!defer::convertible_to<E, Element>))
 -           : Element(static_cast<E &&>(e))
 -         {}
 - 
 -         constexpr Element & get() & noexcept
 -         {
 -             return *this;
 -         }
 -         constexpr Element const & get() const & noexcept
 -         {
 -             return *this;
 -         }
 -         constexpr Element && get() && noexcept
 -         {
 -             return detail::move(*this);
 -         }
 -         constexpr Element const && get() const && noexcept
 -         {
 -             return detail::move(*this);
 -         }
 -     };
 - 
 -     template<typename Element, typename Tag>
 -     class box<Element, Tag, detail::box_compress::coalesce>
 -     {
 -         static Element value;
 - 
 -     public:
 -         constexpr box() noexcept = default;
 -         template<typename E>
 -         constexpr CPP_ctor(box)(E &&)( //
 -             noexcept(true)             //
 -             requires(!defer::same_as<box, detail::decay_t<E>>) &&
 -             defer::constructible_from<Element, E> && defer::convertible_to<E, Element>)
 -         {}
 -         template<typename E>
 -         constexpr explicit CPP_ctor(box)(E &&)( //
 -             noexcept(true)                      //
 -             requires(!defer::same_as<box, detail::decay_t<E>>) &&
 -             defer::constructible_from<Element, E> && (!defer::convertible_to<E, Element>))
 -         {}
 - 
 -         constexpr Element & get() & noexcept
 -         {
 -             return value;
 -         }
 -         constexpr Element const & get() const & noexcept
 -         {
 -             return value;
 -         }
 -         constexpr Element && get() && noexcept
 -         {
 -             return detail::move(value);
 -         }
 -         constexpr Element const && get() const && noexcept
 -         {
 -             return detail::move(value);
 -         }
 -     };
 - 
 -     template<typename Element, typename Tag>
 -     Element box<Element, Tag, detail::box_compress::coalesce>::value{};
 - 
 -     /// \cond
 -     namespace _get_
 -     {
 -         /// \endcond
 -         // Get by tag type
 -         template<typename Tag, typename Element, detail::box_compress BC>
 -         constexpr Element & get(box<Element, Tag, BC> & b) noexcept
 -         {
 -             return b.get();
 -         }
 -         template<typename Tag, typename Element, detail::box_compress BC>
 -         constexpr Element const & get(box<Element, Tag, BC> const & b) noexcept
 -         {
 -             return b.get();
 -         }
 -         template<typename Tag, typename Element, detail::box_compress BC>
 -         constexpr Element && get(box<Element, Tag, BC> && b) noexcept
 -         {
 -             return detail::move(b).get();
 -         }
 -         // Get by index
 -         template<std::size_t I, typename Element, detail::box_compress BC>
 -         constexpr Element & get(box<Element, meta::size_t<I>, BC> & b) noexcept
 -         {
 -             return b.get();
 -         }
 -         template<std::size_t I, typename Element, detail::box_compress BC>
 -         constexpr Element const & get(
 -             box<Element, meta::size_t<I>, BC> const & b) noexcept
 -         {
 -             return b.get();
 -         }
 -         template<std::size_t I, typename Element, detail::box_compress BC>
 -         constexpr Element && get(box<Element, meta::size_t<I>, BC> && b) noexcept
 -         {
 -             return detail::move(b).get();
 -         }
 -         /// \cond
 -     } // namespace _get_
 -     /// \endcond
 -     /// @}
 - } // namespace ranges
 - 
 - RANGES_DIAGNOSTIC_POP
 - 
 - #endif
 
 
  |