// Copyright (c) 2016-2021 Antony Polukhin // // 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_PFR_DETAIL_FUNCTIONAL_HPP #define BOOST_PFR_DETAIL_FUNCTIONAL_HPP #pragma once #include #include #include namespace boost { namespace pfr { namespace detail { template struct equal_impl { template constexpr static bool cmp(const T& v1, const U& v2) noexcept { return ::boost::pfr::detail::sequence_tuple::get(v1) == ::boost::pfr::detail::sequence_tuple::get(v2) && equal_impl::cmp(v1, v2); } }; template struct equal_impl { template constexpr static bool cmp(const T&, const U&) noexcept { return T::size_v == U::size_v; } }; template struct not_equal_impl { template constexpr static bool cmp(const T& v1, const U& v2) noexcept { return ::boost::pfr::detail::sequence_tuple::get(v1) != ::boost::pfr::detail::sequence_tuple::get(v2) || not_equal_impl::cmp(v1, v2); } }; template struct not_equal_impl { template constexpr static bool cmp(const T&, const U&) noexcept { return T::size_v != U::size_v; } }; template struct less_impl { template constexpr static bool cmp(const T& v1, const U& v2) noexcept { return sequence_tuple::get(v1) < sequence_tuple::get(v2) || (sequence_tuple::get(v1) == sequence_tuple::get(v2) && less_impl::cmp(v1, v2)); } }; template struct less_impl { template constexpr static bool cmp(const T&, const U&) noexcept { return T::size_v < U::size_v; } }; template struct less_equal_impl { template constexpr static bool cmp(const T& v1, const U& v2) noexcept { return sequence_tuple::get(v1) < sequence_tuple::get(v2) || (sequence_tuple::get(v1) == sequence_tuple::get(v2) && less_equal_impl::cmp(v1, v2)); } }; template struct less_equal_impl { template constexpr static bool cmp(const T&, const U&) noexcept { return T::size_v <= U::size_v; } }; template struct greater_impl { template constexpr static bool cmp(const T& v1, const U& v2) noexcept { return sequence_tuple::get(v1) > sequence_tuple::get(v2) || (sequence_tuple::get(v1) == sequence_tuple::get(v2) && greater_impl::cmp(v1, v2)); } }; template struct greater_impl { template constexpr static bool cmp(const T&, const U&) noexcept { return T::size_v > U::size_v; } }; template struct greater_equal_impl { template constexpr static bool cmp(const T& v1, const U& v2) noexcept { return sequence_tuple::get(v1) > sequence_tuple::get(v2) || (sequence_tuple::get(v1) == sequence_tuple::get(v2) && greater_equal_impl::cmp(v1, v2)); } }; template struct greater_equal_impl { template constexpr static bool cmp(const T&, const U&) noexcept { return T::size_v >= U::size_v; } }; template constexpr void hash_combine(SizeT& seed, SizeT value) noexcept { seed ^= value + 0x9e3779b9 + (seed<<6) + (seed>>2); } template auto compute_hash(const T& value, long /*priority*/) -> decltype(std::hash()(value)) { return std::hash()(value); } template std::size_t compute_hash(const T& /*value*/, int /*priority*/) { static_assert(sizeof(T) && false, "====================> Boost.PFR: std::hash not specialized for type T"); return 0; } template struct hash_impl { template constexpr static std::size_t compute(const T& val) noexcept { std::size_t h = detail::compute_hash( ::boost::pfr::detail::sequence_tuple::get(val), 1L ); detail::hash_combine(h, hash_impl::compute(val) ); return h; } }; template struct hash_impl { template constexpr static std::size_t compute(const T&) noexcept { return 0; } }; ///////////////////// Define min_element and to avoid inclusion of constexpr std::size_t min_size(std::size_t x, std::size_t y) noexcept { return x < y ? x : y; } template