25 #ifndef GEOS_COMMON_FORMAT_ENUMSTRINGS_HPP 
   26 #define GEOS_COMMON_FORMAT_ENUMSTRINGS_HPP 
   32 #include "common/format/Format.hpp" 
   35 #include <type_traits> 
   48 template< 
typename ... ARGS >
 
   49 constexpr 
int countArgs( ARGS ... )
 
   51   return sizeof...( ARGS );
 
   79 #define ENUM_STRINGS( ENUM, ... )                                     \ 
   80   inline auto const & getEnumStrings( ENUM const )                    \ 
   82     static constexpr char const * ss[] { __VA_ARGS__ };               \ 
   86   inline auto const & getEnumTypeNameString( ENUM const )             \ 
   91   inline std::ostream & operator<<( std::ostream & os, ENUM const e ) \ 
   93     os << EnumStrings< ENUM >::toString( e );                         \ 
   97   inline std::istream & operator>>( std::istream & is, ENUM & e )     \ 
  100     e = EnumStrings< ENUM >::fromString( s );                         \ 
  104   inline string toString( ENUM const e )                              \ 
  106     return EnumStrings< ENUM >::toString( e );                        \ 
  109   static_assert( std::is_enum< ENUM >::value, "Not an enumeration" )
 
  115 template< 
typename ENUM >
 
  137   static string concat( 
string const & delim = 
" " )
 
  139     auto const & strings = 
get();
 
  140     return stringutilities::join( std::begin( strings ), std::end( strings ), delim );
 
  152     auto const & strings = 
get();
 
  153     std::size_t size = std::distance( std::begin( strings ), std::end( strings ) );
 
  155     GEOS_THROW_IF( index >= LvArray::integerConversion< base_type >( size ),
 
  156                    "Invalid value " << index << 
" of type " << getEnumTypeNameString( 
enum_type{} ) << 
". Valid range is 0.." << size - 1,
 
  158     return strings[ index ];
 
  168     auto const & strings = 
get();
 
  169     auto const it = std::find( std::begin( strings ), std::end( strings ), s );
 
  171                    "Invalid value '" << s << 
"' of type " << getEnumTypeNameString( 
enum_type{} ) << 
". Valid options are: " << 
concat( 
", " ),
 
  173     enum_type const e = 
static_cast< enum_type >( LvArray::integerConversion< base_type >( std::distance( std::begin( strings ), it ) ) );
 
  180 IS_VALID_EXPRESSION( HasEnumStrings, ENUM, getEnumStrings( std::declval< ENUM >() ) );
 
  186 template< 
typename Enum >
 
  187 struct GEOS_FMT_NS::formatter< Enum, std::enable_if_t< std::is_enum< Enum >::value && geos::internal::HasEnumStrings< Enum >, char > >
 
  188   : GEOS_FMT_NS::formatter< std::string >
 
  190   template< 
typename FormatContext >
 
  191   auto format( Enum e, FormatContext & ctx )
 const 
  193     return formatter< std::string >::format( toString( e ), ctx );
 
  198 template< 
typename Enum >
 
  199 struct GEOS_FMT_NS::formatter< Enum, std::enable_if_t< std::is_enum< Enum >::value && !geos::internal::HasEnumStrings< Enum >, char > >
 
  200   : GEOS_FMT_NS::formatter< std::underlying_type_t< Enum > >
 
  202   template< 
typename FormatContext >
 
  203   auto format( Enum e, FormatContext & ctx )
 const 
  205     return GEOS_FMT_NS::formatter< std::underlying_type_t< Enum > >::format( toUnderlying( e ), ctx );
 
#define GEOS_THROW_IF(EXP, msg, TYPE)
Conditionally throw an exception.
 
std::size_t size_t
Unsigned size type.
 
Provides enum <-> string conversion facilities.
 
static enum_type fromString(string const &s)
Convert string to enum.
 
static auto const  & get()
 
ENUM enum_type
Alias for the enumeration type.
 
std::underlying_type_t< ENUM > base_type
Alias for enum's underlying fundamental type.
 
static string concat(string const &delim=" ")
Get a list of valid options as a delimited string.
 
static string toString(enum_type const &e)
Convert enum to string.