Header file range/v3/utility/move.hpp

#include <meta/meta.hpp>

#include <range/v3/range_fwd.hpp>

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

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

namespace ranges
{
    inline namespace v3
    {
        namespace aux
        {
            struct move_fn;
            
            inline namespace 
            {
                constexpr auto& move = static_const<move_fn>::value;
            }
            
            template <typename T>
            meta::_t<std::remove_reference<T>>&& operator|(T&& t, move_fn move) noexcept;
            
            template <typename R>
            using move_t = meta::if_<std::is_reference<R>, meta::_t<std::remove_reference<R>>&&, detail::decay_t<R>>;
        }
        
        namespace adl_move_detail
        {
            template <typename I, typename R = decltype(*std::declval<I const&>())>
            )>aux::move_t<R> indirect_move(I const& i) noexcept(noexcept(static_cast<aux::move_t<R>>(aux::move(*i))));
            
            struct indirect_move_fn
            {
                template <typename I>
                decltype(indirect_move(i)) operator()(I const& i) const noexcept(noexcept(decltype(indirect_move(i))(indirect_move(i))));
            };
        }
        
        inline namespace 
        {
            constexpr auto& indirect_move = static_const<adl_move_detail::indirect_move_fn>::value;
        }
        
        namespace detail
        {
            template <typename I, typename O>
            meta::and_<std::is_constructible<meta::_t<value_type<I>>, decltype(indirect_move(std::declval<I&>()))>, std::is_assignable<decltype(*std::declval<O&>()), decltype(indirect_move(std::declval<I&>()))>> is_indirectly_movable_(int);
            
            template <typename I, typename O>
            std::false_type is_indirectly_movable_(long);
            
            template <typename I, typename O>
            meta::and_<std::is_nothrow_constructible<meta::_t<value_type<I>>, decltype(indirect_move(std::declval<I&>()))>, std::is_nothrow_assignable<decltype(*std::declval<O&>()), decltype(indirect_move(std::declval<I&>()))>> is_nothrow_indirectly_movable_(int);
            
            template <typename I, typename O>
            std::false_type is_nothrow_indirectly_movable_(long);
        }
        
        template <typename I, typename O>
        struct is_indirectly_movable
        : decltype(detail::is_indirectly_movable_<I, O>(42))
        {};
        
        template <typename I, typename O>
        struct is_nothrow_indirectly_movable
        : decltype(detail::is_nothrow_indirectly_movable_<I, O>(42))
        {};
    }
}

Variable ranges::v3::aux::move

constexpr auto& move = static_const<move_fn>::value;

move_fn


Function template ranges::v3::aux::operator|<T>

template <typename T>
meta::_t<std::remove_reference<T>>&& operator|(T&& t, move_fn move) noexcept;

move_fn


Alias template ranges::v3::aux::move_t<R>

template <typename R>
using move_t = meta::if_<std::is_reference<R>, meta::_t<std::remove_reference<R>>&&, detail::decay_t<R>>;

move_fn