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.