// Copyright (C) 2022-2023 Christian Mazakas // Copyright (C) 2024 Braden Ganetsky // // 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) #ifndef BOOST_UNORDERED_DETAIL_TYPE_TRAITS_HPP #define BOOST_UNORDERED_DETAIL_TYPE_TRAITS_HPP #include #if defined(BOOST_HAS_PRAGMA_ONCE) #pragma once #endif #include #if !defined(BOOST_NO_CXX17_DEDUCTION_GUIDES) #include #endif #include #include // BOOST_UNORDERED_TEMPLATE_DEDUCTION_GUIDES #if !defined(BOOST_UNORDERED_TEMPLATE_DEDUCTION_GUIDES) #if !defined(BOOST_NO_CXX17_DEDUCTION_GUIDES) #define BOOST_UNORDERED_TEMPLATE_DEDUCTION_GUIDES 1 #endif #endif #if !defined(BOOST_UNORDERED_TEMPLATE_DEDUCTION_GUIDES) #define BOOST_UNORDERED_TEMPLATE_DEDUCTION_GUIDES 0 #endif namespace boost { namespace unordered { namespace detail { template struct type_identity { using type = T; }; template struct make_void { typedef void type; }; template using void_t = typename make_void::type; template struct is_complete : std::false_type { }; template struct is_complete > : std::true_type { }; template using is_complete_and_move_constructible = typename std::conditional::value, std::is_move_constructible, std::false_type>::type; #if BOOST_WORKAROUND(BOOST_LIBSTDCXX_VERSION, < 50000) /* std::is_trivially_default_constructible not provided */ template struct is_trivially_default_constructible : public std::integral_constant::value && std::has_trivial_default_constructor::value> { }; #else using std::is_trivially_default_constructible; #endif #if BOOST_WORKAROUND(BOOST_LIBSTDCXX_VERSION, < 50000) /* std::is_trivially_copy_constructible not provided */ template struct is_trivially_copy_constructible : public std::integral_constant::value && std::has_trivial_copy_constructor::value> { }; #else using std::is_trivially_copy_constructible; #endif #if BOOST_WORKAROUND(BOOST_LIBSTDCXX_VERSION, < 50000) /* std::is_trivially_copy_assignable not provided */ template struct is_trivially_copy_assignable : public std::integral_constant::value && std::has_trivial_copy_assign::value> { }; #else using std::is_trivially_copy_assignable; #endif namespace type_traits_detail { using std::swap; template struct is_nothrow_swappable_helper { constexpr static bool const value = false; }; template struct is_nothrow_swappable_helper(), std::declval()))> > { constexpr static bool const value = noexcept(swap(std::declval(), std::declval())); }; } // namespace type_traits_detail template struct is_nothrow_swappable : public std::integral_constant::value> { }; //////////////////////////////////////////////////////////////////////////// // Type checkers used for the transparent member functions added by C++20 // and up template struct is_transparent : public std::false_type { }; template struct is_transparent > : public std::true_type { }; template struct are_transparent { static bool const value = is_transparent::value && is_transparent::value; }; template struct transparent_non_iterable { typedef typename UnorderedMap::hasher hash; typedef typename UnorderedMap::key_equal key_equal; typedef typename UnorderedMap::iterator iterator; typedef typename UnorderedMap::const_iterator const_iterator; static bool const value = are_transparent::value && !std::is_convertible::value && !std::is_convertible::value; }; template using remove_cvref_t = typename std::remove_cv::type>::type; template using is_similar = std::is_same, remove_cvref_t >; template struct is_similar_to_any : std::false_type { }; template struct is_similar_to_any : std::conditional::value, is_similar, is_similar_to_any >::type { }; #if BOOST_UNORDERED_TEMPLATE_DEDUCTION_GUIDES // https://eel.is/c++draft/container.requirements#container.alloc.reqmts-34 // https://eel.is/c++draft/container.requirements#unord.req.general-243 template constexpr bool const is_input_iterator_v = !std::is_integral::value; template struct is_allocator { constexpr static bool const value = false; }; template struct is_allocator().allocate(std::size_t{}))> > { constexpr static bool const value = true; }; template constexpr bool const is_allocator_v = is_allocator::value; template constexpr bool const is_hash_v = !std::is_integral::value && !is_allocator_v; template constexpr bool const is_pred_v = !is_allocator_v

; template using iter_key_t = typename std::iterator_traits::value_type::first_type; template using iter_val_t = typename std::iterator_traits::value_type::second_type; template using iter_to_alloc_t = typename std::pair const, iter_val_t >; #endif #if BOOST_CXX_VERSION < 201703L template constexpr typename std::add_const::type& as_const(T& t) noexcept { return t; } template void as_const(const T&&) = delete; #else using std::as_const; #endif } // namespace detail } // namespace unordered } // namespace boost #endif // BOOST_UNORDERED_DETAIL_TYPE_TRAITS_HPP