Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <functional>
- #include <tuple>
- #include <utility>
- namespace details {
- template<typename Type, typename = std::void_t<>>
- struct is_transparent_compare : std::false_type { };
- template<typename Type>
- struct is_transparent_compare<Type, std::void_t<typename Type::is_transparent>> : std::true_type { };
- template<typename Type>
- constexpr bool is_transparent_compare_v = is_transparent_compare<Type>::value;
- template<std::size_t Index, typename Tuple>
- struct tuple_default_compare {
- using type = std::less<std::tuple_element_t<Index, Tuple>>;
- };
- template<std::size_t Index>
- struct tuple_default_compare<Index, void> {
- using type = std::less<>;
- };
- template<std::size_t Index, typename Tuple>
- using tuple_default_compare_t = typename tuple_default_compare<Index, Tuple>::type;
- template<std::size_t Index, typename Tuple>
- constexpr decltype(auto) get(Tuple&& tuple) noexcept {
- using std::get;
- return get<Index>(std::forward<Tuple>(tuple));
- }
- }
- template<std::size_t Index, typename Tuple = void, typename Compare = details::tuple_default_compare_t<Index, Tuple>>
- struct tuple_compare {
- public:
- constexpr explicit tuple_compare() = default;
- constexpr explicit tuple_compare(const Compare& compare) noexcept(std::is_nothrow_copy_constructible_v<Compare>)
- : compare(compare) { }
- constexpr bool operator()(const Tuple& left, const Tuple& right) const
- noexcept(std::is_nothrow_invocable<Compare>, const std::tuple_element_t<Index, Tuple>&, const std::tuple_element_t<Index, Tuple>&) {
- return compare(details::get<Index>(left), details::get<Index>(right));
- }
- private:
- Compare compare;
- };
- template<std::size_t Index, typename Compare>
- struct tuple_compare<Index, void, Compare> {
- public:
- static_assert(details::is_transparent_compare_v<Compare>, "Compare must be transparent compare");
- using is_transparent = int;
- constexpr explicit tuple_compare() = default;
- constexpr explicit tuple_compare(const Compare& compare) noexcept(std::is_nothrow_copy_constructible_v<Compare>)
- : compare(compare) { }
- template<typename Left, typename Right>
- constexpr decltype(auto) operator()(Left&& left, Right&& right) const
- noexcept(noexcept(std::declval<Compare>()(details::get<Index>(std::forward<Left>(left)),
- details::get<Index>(std::forward<Right>(right))))) {
- return compare(details::get<Index>(std::forward<Left>(left)), details::get<Index>(std::forward<Right>(right)));
- }
- private:
- Compare compare;
- };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement