Program Listing for File OrderKey.h

↰ Return to documentation for file (ADS/priority/OrderKey.h)

/*--------------------------------------------------------------------------*/
/*---------------------------- File OrderKey.h -----------------------------*/
/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/
/*----------------------------- DEFINITIONS --------------------------------*/
/*--------------------------------------------------------------------------*/

#ifndef __ADS_OrderKey
 #define __ADS_OrderKey
                      /* self-identification: #endif constant */

/*--------------------------------------------------------------------------*/
/*------------------------------ INCLUDES ----------------------------------*/
/*--------------------------------------------------------------------------*/

#include "ADS/sort/RadixSort.h"

#include <cstdint>
#include <functional>
#include <type_traits>
#include <utility>

/*--------------------------------------------------------------------------*/
/*--------------------------- NAMESPACE ------------------------------------*/
/*--------------------------------------------------------------------------*/

namespace ADS::detail {

template< class T >
struct IsNumberPair : std::false_type {};

template< class A , class B >
struct IsNumberPair< std::pair< A , B > > : std::bool_constant<
 RadixKey< A > && RadixKey< B > && ( sizeof( A ) + sizeof( B ) <= 8 ) > {};

template< class T >
concept OrderKeyed = RadixKey< T > || IsNumberPair< T >::value;

template< class T , class C >
inline constexpr bool kAscending = std::is_same_v< C , std::less<> > ||
                                   std::is_same_v< C , std::less< T > >;

template< class T , class C >
inline constexpr bool kDescending = std::is_same_v< C , std::greater<> > ||
                                    std::is_same_v< C , std::greater< T > >;

template< class T , class C >
inline constexpr bool kKeyed = OrderKeyed< T > &&
                               ( kAscending< T , C > || kDescending< T , C > );

template< OrderKeyed T >
[[nodiscard]] inline auto orderKey( const T & x )
{
 if constexpr( RadixKey< T > )
  return( radixKey( x ) );
 else {
  using A = typename T::first_type;
  using B = typename T::second_type;
  using U = std::conditional_t< sizeof( A ) + sizeof( B ) <= 4 ,
                                std::uint32_t , std::uint64_t >;
  return( U( ( U( radixKey( x.first ) ) << ( 8 * sizeof( B ) ) ) |
             U( radixKey( x.second ) ) ) );
  }
 }

template< class C , class T >
 requires kKeyed< T , C >
[[nodiscard]] inline auto orderKeyBy( const T & x )
{
 const auto k = orderKey( x );
 if constexpr( kDescending< T , C > )
  return( decltype( k )( ~k ) );
 else
  return( k );
 }

}  // end( namespace ADS::detail )

/*--------------------------------------------------------------------------*/

#endif  /* OrderKey.h included */

/*--------------------------------------------------------------------------*/
/*-------------------------- End File OrderKey.h ---------------------------*/
/*--------------------------------------------------------------------------*/