Header file range/v3/utility/box.hpp

#include <meta/meta.hpp>

#include <range/v3/range_fwd.hpp>

#include <range/v3/utility/get.hpp>

#include <range/v3/utility/concepts.hpp>

namespace ranges
{
    inline namespace v3
    {
        template <typename T>
        struct mutable_;
        
        template <typename T>
        struct mutable_<std::atomic<T>>
        {
            mutable std::atomic<T> value;
            
            mutable_() = default;
            
            mutable_(mutable_const& that);
            
            explicit constexpr mutable_(T&& t);
            
            explicit constexpr mutable_(T const& t);
            
            mutable_const& operator=(mutable_const& that) const;
            
            mutable_const& operator=(T&& t) const;
            
            mutable_const& operator=(T const& t) const;
            
            operator T() const;
            
            T exchange(T desired);
            
            operator std::atomic<T>&() const &;
        };
        
        template <typename T, T v>
        struct constant
        {
            constant() = default;
            
            explicit constexpr constant(T const&);
            
            constant& operator=(T const&);
            
            constant const& operator=(T const&) const;
            
            constexpr operator T() const;
            
            constexpr T exchange(T const&) const;
        };
        
        namespace detail
        {
            enum class box_compress
            {
                none,
                ebo,
                coalesce,
            };
            
            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_(...);
            
            template <typename T, typename = meta::if_<meta::strict_and<std::is_empty<T>, meta::not_<detail::is_final<T>>>>>
            constexpr box_compress box_compression_(long);
            
            template <typename T, typename = meta::if_<meta::strict_and<std::is_empty<T>, std::is_trivial<T>, std::is_default_constructible<T>>>>
            constexpr box_compress box_compression_(int);
            
            template <typename T>
            constexpr box_compress box_compression();
        }
        
        template <typename Element, typename Tag = void, detail::box_compress=detail::box_compression<Element>()>
        class box
        {
        public:
            template <int _concept_requires_194 = 42, typename std::enable_if<(_concept_requires_194==43)||(std::is_default_constructible<Element>::value), int>::type=0>
            constexpr box() noexcept(std::is_nothrow_default_constructible<Element>::value);
            
            template <typename E, int _concept_requires_200 = 42, typename std::enable_if<(_concept_requires_200==43)||(std::is_constructible<Element, E>::value&&std::is_convertible<E, Element>::value), int>::type=0>
            constexpr box(E&& e) noexcept(std::is_nothrow_constructible<Element, E>::value);
            
            template <typename E, int _concept_requires_206 = 42, typename std::enable_if<(_concept_requires_206==43)||(std::is_constructible<Element, E>::value&&!std::is_convertible<E, Element>::value), int>::type=0>
            explicit constexpr box(E&& e) noexcept(std::is_nothrow_constructible<Element, E>::value);
            
            constexpr Element& get() & noexcept;
            
            constexpr Element const& get() const & noexcept;
            
            constexpr Element&& get() && noexcept;
        };
        
        template <typename Element, typename Tag>
        class box<Element, Tag, detail::box_compress::ebo>
        {
        public:
            template <int _concept_requires_231 = 42, typename std::enable_if<(_concept_requires_231==43)||(std::is_default_constructible<Element>::value), int>::type=0>
            constexpr box() noexcept(std::is_nothrow_default_constructible<Element>::value);
            
            template <typename E, int _concept_requires_237 = 42, typename std::enable_if<(_concept_requires_237==43)||(std::is_constructible<Element, E>::value&&std::is_convertible<E, Element>::value), int>::type=0>
            constexpr box(E&& e) noexcept(std::is_nothrow_constructible<Element, E>::value);
            
            template <typename E, int _concept_requires_243 = 42, typename std::enable_if<(_concept_requires_243==43)||(std::is_constructible<Element, E>::value&&!std::is_convertible<E, Element>::value), int>::type=0>
            explicit constexpr box(E&& e) noexcept(std::is_nothrow_constructible<Element, E>::value);
            
            constexpr Element& get() & noexcept;
            
            constexpr Element const& get() const & noexcept;
            
            constexpr Element&& get() && noexcept;
        };
        
        template <typename Element, typename Tag>
        class box<Element, Tag, detail::box_compress::coalesce>
        {
        public:
            constexpr box() noexcept;
            
            template <typename E, int _concept_requires_271 = 42, typename std::enable_if<(_concept_requires_271==43)||(std::is_constructible<Element, E>::value&&std::is_convertible<E, Element>::value), int>::type=0>
            constexpr box(E&&) noexcept;
            
            template <typename E, int _concept_requires_275 = 42, typename std::enable_if<(_concept_requires_275==43)||(std::is_constructible<Element, E>::value&&!std::is_convertible<E, Element>::value), int>::type=0>
            explicit constexpr box(E&&) noexcept;
            
            constexpr Element& get() & noexcept;
            
            constexpr Element const& get() const & noexcept;
            
            constexpr Element&& get() && noexcept;
        };
        
        template <typename Tag, typename Element, detail::box_compress BC>
        constexpr Element& get(box<Element, Tag, BC>& b) noexcept;
        
        template <typename Tag, typename Element, detail::box_compress BC>
        constexpr Element const& get(box<Element, Tag, BC>const& b) noexcept;
        
        template <typename Tag, typename Element, detail::box_compress BC>
        constexpr Element&& get(box<Element, Tag, BC>&& b) noexcept;
        
        template <std::size_t I, typename Element, detail::box_compress BC>
        constexpr Element& get(box<Element, meta::size_t<I>, BC>& b) noexcept;
        
        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;
        
        template <std::size_t I, typename Element, detail::box_compress BC>
        constexpr Element&& get(box<Element, meta::size_t<I>, BC>&& b) noexcept;
    }
}

Class template ranges::v3::mutable_<T>

template <typename T>
struct mutable_
{
    mutable T value;
    
    template <int _concept_requires_38 = 42, typename std::enable_if<(_concept_requires_38==43)||(std::is_default_constructible<T>::value), int>::type=0>
    constexpr mutable_();
    
    explicit constexpr mutable_(T const& t);
    
    explicit constexpr mutable_(T&& t);
    
    mutable_const& operator=(T const& t) const;
    
    mutable_const& operator=(T&& t) const;
    
    constexpr operator T&() const &;
};

@{