25 #include "cafAssert.h"
26 #include "cafJsonDataType.h"
27 #include "cafPortableDataType.h"
29 #include <nlohmann/json.hpp>
36 #include <type_traits>
42 concept enum_type = std::is_enum<T>::value;
66 template <
typename Enum>
67 requires enum_type<Enum>
71 using DataType = Enum;
73 AppEnum() { m_value = EnumMapper::instance()->defaultValue(); }
78 AppEnum(
const std::string& value )
80 m_value = EnumMapper::instance()->defaultValue();
81 setFromLabel( value );
84 auto operator<=>(
const AppEnum& rhs )
const =
default;
86 Enum value()
const {
return m_value; }
87 size_t index()
const {
return EnumMapper::instance()->index( m_value ); }
88 std::string label()
const {
return EnumMapper::instance()->label( m_value ); }
90 AppEnum& operator=( Enum value )
96 void setFromLabel(
const std::string& label )
98 if ( !EnumMapper::instance()->enumVal( m_value, label ) )
100 throw std::runtime_error( label +
" is not a valid option" );
104 void setFromIndex(
size_t index )
106 if ( !EnumMapper::instance()->enumVal( m_value, index ) )
108 throw std::runtime_error( std::to_string( index ) +
" is not a valid option index" );
114 static bool isValid(
const std::string& label ) {
return EnumMapper::instance()->isValid( label ); }
115 static bool isValid(
size_t index ) {
return index < EnumMapper::instance()->size(); }
116 static size_t size() {
return EnumMapper::instance()->size(); }
118 static std::vector<std::string> labels() {
return EnumMapper::instance()->labels(); }
119 static auto fromIndex(
size_t idx )
122 if ( !EnumMapper::instance()->enumVal( val, idx ) )
124 throw std::runtime_error( std::to_string( idx ) +
" is not a valid option index" );
128 static auto fromLabel(
const std::string& label ) {
return AppEnum<Enum>( label ); }
129 static size_t index( Enum enumValue ) {
return EnumMapper::instance()->index( enumValue ); }
130 static std::string label( Enum enumValue ) {
return EnumMapper::instance()->label( enumValue ); }
131 static std::string labelFromIndex(
size_t idx ) {
return label( fromIndex( idx ).value() ); }
140 static void addItem( Enum enumVal,
const std::string& label ) { EnumMapper::instance()->addItem( enumVal, label ); }
142 static void setDefault( Enum defaultEnumValue ) { EnumMapper::instance()->setDefault( defaultEnumValue ); }
156 void addItem( Enum enumVal,
const std::string& label )
158 instance()->m_mapping.push_back( std::make_pair( enumVal, label ) );
161 static EnumMapper* instance()
163 static EnumMapper storedInstance;
164 static bool isInitialized =
false;
165 if ( !isInitialized )
167 isInitialized =
true;
170 return &storedInstance;
173 void setDefault( Enum defaultEnumValue )
175 m_defaultValue = defaultEnumValue;
176 m_defaultValueIsSet =
true;
179 Enum defaultValue()
const
181 if ( m_defaultValueIsSet )
183 return m_defaultValue;
187 CAFFA_ASSERT( m_mapping.size() );
188 return m_mapping[0].first;
192 bool isValid(
const std::string& label )
const
195 for ( idx = 0; idx < m_mapping.size(); ++idx )
197 if ( label == m_mapping[idx].second )
return true;
203 size_t size()
const {
return m_mapping.size(); }
205 bool enumVal( Enum& value,
const std::string& label )
const
207 value = defaultValue();
209 for ( idx = 0; idx < m_mapping.size(); ++idx )
211 if ( label == m_mapping[idx].second )
213 value = m_mapping[idx].first;
220 bool enumVal( Enum& value,
size_t index )
const
222 value = defaultValue();
223 if ( index < m_mapping.size() )
225 value = m_mapping[index].first;
232 size_t index( Enum value )
const
234 for (
size_t i = 0; i < m_mapping.size(); ++i )
236 if ( value == m_mapping[i].first )
return i;
238 throw std::runtime_error(
"AppEnum does not have the value " + std::to_string(
static_cast<int>( value ) ) );
241 std::string label( Enum value )
const
243 for (
const auto& [enumVal, label] : m_mapping )
245 if ( value == enumVal )
return label;
247 throw std::runtime_error(
"AppEnum does not have the value " + std::to_string(
static_cast<int>( value ) ) );
250 std::vector<std::string> labels()
const
252 std::vector<std::string> labelList;
253 for (
const auto& [ignore, label] : m_mapping )
255 labelList.push_back( label );
262 : m_defaultValueIsSet(
false )
266 std::vector<std::pair<Enum, std::string>> m_mapping;
268 bool m_defaultValueIsSet;
272 template <
typename EnumType>
275 static std::string name()
278 std::stringstream ss;
280 for (
size_t i = 0; i < labels.size(); ++i )
282 if ( i > 0u ) ss <<
",";
290 template <
typename EnumType>
293 static std::string name()
296 std::stringstream ss;
298 for (
size_t i = 0; i < labels.size(); ++i )
300 if ( i > 0u ) ss <<
",";
308 template <
typename EnumType>
311 static nlohmann::json type()
313 auto values = nlohmann::json::array();
316 values.push_back( entry );
318 auto object = nlohmann::json::object();
319 object[
"enum"] = values;
328 template <
typename Enum>
334 appEnum.setFromLabel( label );
339 template <
typename Enum>
342 std::string label = appEnum.label();
343 str << appEnum.label();
347 template <
typename Enum>
348 void to_json( nlohmann::json& jsonValue,
const AppEnum<Enum>& appEnum )
350 std::stringstream stream;
352 jsonValue = stream.str();
355 template <
typename Enum>
356 void from_json(
const nlohmann::json& jsonValue, AppEnum<Enum>& appEnum )
358 std::stringstream stream( jsonValue.get<std::string>() );
Definition: cafAppEnum.h:69
Main Caffa namespace.
Definition: __init__.py:1
std::istream & operator>>(std::istream &str, caffa::AppEnum< Enum > &appEnum)
Definition: cafAppEnum.h:329
Definition: cafJsonDataType.h:37
Definition: cafPortableDataType.h:35