GEOSX
EnumStrings.hpp
Go to the documentation of this file.
1 /*
2  * ------------------------------------------------------------------------------------------------------------
3  * SPDX-License-Identifier: LGPL-2.1-only
4  *
5  * Copyright (c) 2018-2020 Lawrence Livermore National Security LLC
6  * Copyright (c) 2018-2020 The Board of Trustees of the Leland Stanford Junior University
7  * Copyright (c) 2018-2020 Total, S.A
8  * Copyright (c) 2019- GEOSX Contributors
9  * All rights reserved
10  *
11  * See top level LICENSE, COPYRIGHT, CONTRIBUTORS, NOTICE, and ACKNOWLEDGEMENTS files for details.
12  * ------------------------------------------------------------------------------------------------------------
13  */
14 
24 #ifndef GEOSX_COMMON_ENUM_HPP_
25 #define GEOSX_COMMON_ENUM_HPP_
26 
27 #include "codingUtilities/StringUtilities.hpp"
28 #include "common/DataTypes.hpp"
29 #include "common/Logger.hpp"
30 
31 #include <iostream>
32 #include <sstream>
33 #include <array>
34 #include <type_traits>
35 #include <algorithm>
36 
37 namespace geosx
38 {
39 
40 namespace internal
41 {
47 template< typename ... ARGS >
48 constexpr int countArgs( ARGS ... )
49 {
50  return sizeof...( ARGS );
51 }
52 }
53 
69 #define ENUM_STRINGS( ENUM, ... ) \
70  static_assert( std::is_enum< ENUM >::value, "Not an enumeration" ); \
71  \
72  inline auto const & getEnumStrings( ENUM const ) \
73  { \
74  constexpr int N = internal::countArgs( __VA_ARGS__ ); \
75  static constexpr std::array< char const *, N > ss{ __VA_ARGS__ }; \
76  return ss; \
77  } \
78  \
79  inline std::ostream & operator<<( std::ostream & os, ENUM const e ) \
80  { \
81  os << EnumStrings< ENUM >::toString( e ); \
82  return os; \
83  } \
84  \
85  inline std::istream & operator>>( std::istream & is, ENUM & e ) \
86  { \
87  string s; is >> s; \
88  e = EnumStrings< ENUM >::fromString( s ); \
89  return is; \
90  }
91 
96 template< typename ENUM >
98 {
100  using enum_type = ENUM;
101 
103  using base_type = std::underlying_type_t< ENUM >;
104 
108  static auto const & get()
109  {
110  return getEnumStrings( enum_type{} ); // invoke ADL
111  }
112 
118  static string concat( string const & delim = " " )
119  {
120  auto const & strings = get();
121  return ::geosx::stringutilities::strjoin( begin( strings ), end( strings ), delim );
122  }
123 
131  static string toString( enum_type const & e )
132  {
133  auto const & strings = get();
134  base_type const index = static_cast< base_type >( e );
135  GEOSX_ERROR_IF_GE_MSG( index, LvArray::integerConversion< base_type >( strings.size() ),
136  "Unrecognized value of " << TypeName< ENUM >::brief() << ": " << index << ".\n" <<
137  "Valid range is 0.." << strings.size() - 1 );
138  return strings[ index ];
139  }
140 
146  static enum_type fromString( string const & s )
147  {
148  auto const & strings = get();
149  auto const it = std::find( begin( strings ), end( strings ), s );
150  GEOSX_ERROR_IF( it == strings.end(),
151  "'" << s << "' is not a recognized value of " << TypeName< enum_type >::brief() << ".\n" <<
152  "Valid options are: \n " << concat( "\n " ) );
153  enum_type const e = static_cast< enum_type >( LvArray::integerConversion< base_type >( std::distance( begin( strings ), it ) ) );
154  return e;
155  }
156 };
157 
158 namespace internal
159 {
160 IS_VALID_EXPRESSION( HasEnumStrings, ENUM, getEnumStrings( std::declval< ENUM >() ) );
161 }
162 
167 template< typename ENUM >
168 struct TypeRegex< ENUM, std::enable_if_t< internal::HasEnumStrings< ENUM > > >
169 {
173  static std::string get()
174  {
175  return EnumStrings< ENUM >::concat( "|" );
176  }
177 };
178 
179 } // namespace geosx
180 
181 #endif //GEOSX_COMMON_ENUM_HPP_
ENUM enum_type
Alias for the enumeration type.
Utility class for querying type names at runtime.
Definition: DataTypes.hpp:958
std::ptrdiff_t find(T const *const LVARRAY_RESTRICT ptr, std::ptrdiff_t const size, T const &value, Compare &&comp=Compare())
static string concat(string const &delim=" ")
Get a list of valid options as a delimited string.
#define GEOSX_ERROR_IF_GE_MSG(lhs, rhs, msg)
Raise a hard error if one value compares greater than or equal to the other.
Definition: Logger.hpp:202
std::underlying_type_t< ENUM > base_type
Alias for enum&#39;s underlying fundamental type.
static string toString(enum_type const &e)
Convert enum to string.
static enum_type fromString(string const &s)
Convert string to enum.
Provides enum <-> string conversion facilities.
Definition: EnumStrings.hpp:97
Extension point for custom types to provide a validation regexp to schema.
Definition: DataTypes.hpp:941
static string brief()
Definition: DataTypes.hpp:971
std::string string
String type.
Definition: DataTypes.hpp:131
#define GEOSX_ERROR_IF(EXP, msg)
Conditionally raise a hard error and terminate the program.
Definition: Logger.hpp:103
#define IS_VALID_EXPRESSION(NAME, T,...)
Macro that expands to a static constexpr bool with one template argument which is true only if the ex...