// Copyright 2015, Tobias Hermann and the FunctionalPlus contributors. // https://github.com/Dobiasd/FunctionalPlus // Distributed under 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) #pragma once #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace fplus { namespace internal { #ifdef __GNUC__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Weffc++" #endif template struct has_order : public std::false_type {}; template struct has_order> : public std::true_type {}; template struct has_order> : public std::true_type {}; template struct has_order> : public std::true_type {}; template struct has_order> : public std::true_type {}; template struct has_order> : public std::true_type {}; template struct has_order> : public std::false_type {}; template struct has_order> : public std::true_type {}; template struct has_order> : public std::true_type {}; template struct has_order> : public std::false_type {}; template struct has_order> : public std::true_type {}; // http://stackoverflow.com/a/33828321/1866775 template::lowest()> struct same_cont_new_t : public std::false_type{}; template struct same_cont_new_t, NewT, SizeOffset> { static_assert(SizeOffset != std::numeric_limits::lowest(), "Size of std::array must be known at compile-time."); typedef typename std::array(static_cast(N) + SizeOffset)> type; }; template struct same_cont_new_t, NewT, SizeOffset> { typedef typename std::vector type; }; template struct same_cont_new_t, NewT, SizeOffset> { typedef typename std::deque type; }; template struct same_cont_new_t, NewT, SizeOffset> { typedef typename std::forward_list type; }; template struct same_cont_new_t, NewT, SizeOffset> { typedef typename std::list type; }; template struct same_cont_new_t, NewT, SizeOffset> { typedef typename std::set type; }; template struct same_cont_new_t, NewT, SizeOffset> { typedef typename std::stack type; }; template struct same_cont_new_t, NewT, SizeOffset> { typedef typename std::queue type; }; template struct same_cont_new_t, NewT, SizeOffset> { typedef typename std::priority_queue type; }; template struct same_cont_new_t, NewT, SizeOffset> { typedef typename std::basic_string type; }; template struct SameMapTypeNewTypes : public std::false_type {}; template struct SameMapTypeNewTypes, NewKey, NewVal> { typedef typename std::map type; }; template struct SameMapTypeNewTypes, NewKey, NewVal> { typedef typename std::unordered_map type; }; #ifdef __GNUC__ #pragma GCC diagnostic pop #endif template< typename ContIn, typename F, int SizeOffset = std::numeric_limits::lowest(), typename T = typename ContIn::value_type, typename ContOut = typename same_cont_new_t>, SizeOffset>::type> struct same_cont_new_t_from_unary_f { typedef ContOut type; }; template< typename ContIn, typename F, typename T1, typename T2, int SizeOffset = std::numeric_limits::lowest(), typename ContOut = typename same_cont_new_t>, SizeOffset>::type> struct same_cont_new_t_from_binary_f { typedef ContOut type; }; // https://stackoverflow.com/a/44549820/1866775 template struct can_self_assign { using type = std::is_assignable; }; template using can_self_assign_t = typename can_self_assign::type; template struct can_self_assign> { enum { t0 = can_self_assign_t::value, t1 = can_self_assign_t::value, x = t0&&t1 }; using type = std::integral_constant; }; template<> struct can_self_assign> { using type = std::integral_constant; }; template struct can_self_assign> { using type = std::integral_constant::value && can_self_assign_t>::value >; }; template struct reuse_container_bool_t { }; using create_new_container_t = reuse_container_bool_t; using reuse_container_t = reuse_container_bool_t; template struct can_reuse { using dContainer = typename std::decay::type; using can_assign = can_self_assign_t; using cannot_reuse = std::is_lvalue_reference; using value = reuse_container_bool_t; }; template using can_reuse_v = typename can_reuse::value; template struct remove_const_and_ref { using type = typename std::remove_const::type>::type; }; template using remove_const_and_ref_t = typename remove_const_and_ref::type; } // namespace internal } // namespace fplus