Advertisement
Radfler

::tuple_compare

Mar 12th, 2018
110
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.50 KB | None | 0 0
  1. #include <functional>
  2. #include <tuple>
  3. #include <utility>
  4.  
  5. namespace details {
  6.  
  7.     template<typename Type, typename = std::void_t<>>
  8.     struct is_transparent_compare : std::false_type { };
  9.  
  10.     template<typename Type>
  11.     struct is_transparent_compare<Type, std::void_t<typename Type::is_transparent>> : std::true_type { };
  12.  
  13.     template<typename Type>
  14.     constexpr bool is_transparent_compare_v = is_transparent_compare<Type>::value;
  15.  
  16.     template<std::size_t Index, typename Tuple>
  17.     struct tuple_default_compare {
  18.         using type = std::less<std::tuple_element_t<Index, Tuple>>;
  19.     };
  20.  
  21.     template<std::size_t Index>
  22.     struct tuple_default_compare<Index, void> {
  23.         using type = std::less<>;
  24.     };
  25.  
  26.     template<std::size_t Index, typename Tuple>
  27.     using tuple_default_compare_t = typename tuple_default_compare<Index, Tuple>::type;
  28.  
  29.     template<std::size_t Index, typename Tuple>
  30.     constexpr decltype(auto) get(Tuple&& tuple) noexcept {
  31.         using std::get;
  32.         return get<Index>(std::forward<Tuple>(tuple));
  33.     }
  34.  
  35. }
  36.  
  37. template<std::size_t Index, typename Tuple = void, typename Compare = details::tuple_default_compare_t<Index, Tuple>>
  38. struct tuple_compare {
  39.  
  40. public:
  41.  
  42.     constexpr explicit tuple_compare() = default;
  43.  
  44.     constexpr explicit tuple_compare(const Compare& compare) noexcept(std::is_nothrow_copy_constructible_v<Compare>)
  45.         : compare(compare) { }
  46.  
  47.     constexpr bool operator()(const Tuple& left, const Tuple& right) const
  48.         noexcept(std::is_nothrow_invocable<Compare>, const std::tuple_element_t<Index, Tuple>&, const std::tuple_element_t<Index, Tuple>&) {
  49.  
  50.         return compare(details::get<Index>(left), details::get<Index>(right));
  51.  
  52.     }
  53.  
  54. private:
  55.  
  56.     Compare compare;
  57.  
  58. };
  59.  
  60. template<std::size_t Index, typename Compare>
  61. struct tuple_compare<Index, void, Compare> {
  62.  
  63. public:
  64.  
  65.     static_assert(details::is_transparent_compare_v<Compare>, "Compare must be transparent compare");
  66.     using is_transparent = int;
  67.  
  68.     constexpr explicit tuple_compare() = default;
  69.  
  70.     constexpr explicit tuple_compare(const Compare& compare) noexcept(std::is_nothrow_copy_constructible_v<Compare>)
  71.         : compare(compare) { }
  72.  
  73.     template<typename Left, typename Right>
  74.     constexpr decltype(auto) operator()(Left&& left, Right&& right) const
  75.         noexcept(noexcept(std::declval<Compare>()(details::get<Index>(std::forward<Left>(left)),
  76.                                                   details::get<Index>(std::forward<Right>(right))))) {
  77.  
  78.         return compare(details::get<Index>(std::forward<Left>(left)), details::get<Index>(std::forward<Right>(right)));
  79.  
  80.     }
  81.  
  82. private:
  83.  
  84.     Compare compare;
  85.  
  86. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement