25 #include "cafAssert.h" 26 #include "cafLogger.h" 27 #include "cafPortableDataType.h" 33 #include <type_traits> 39 concept enum_type = std::is_enum<T>::value;
63 template <
typename Enum>
64 requires enum_type<Enum>
68 using DataType = Enum;
73 m_value = m_defaultValue;
80 AppEnum(
const std::string& value )
83 m_value = m_defaultValue;
84 setFromLabel( value );
93 throw std::runtime_error(
"The AppEnum has no value!" );
96 auto operator<=>(
const AppEnum& rhs )
const =
default;
98 AppEnum& operator=( Enum value )
104 void setFromLabel(
const std::string& label )
106 auto value = enumVal( label );
113 throw std::runtime_error( label +
" is not a valid option" );
117 void setFromIndex(
size_t index )
119 auto value = enumVal( index );
126 throw std::runtime_error( std::to_string( index ) +
" is not a valid option index" );
130 std::optional<Enum> enumVal(
const std::string& label )
const 132 for (
auto [entryValue, entryLabel] : m_mapping )
134 if ( entryLabel == label )
140 CAFFA_ERROR(
"No label " << label <<
" in AppEnum" );
141 for (
const auto& [entry, entryLabel] : m_mapping )
143 CAFFA_ERROR(
"Found label " << entryLabel <<
"(" << static_cast<int>( entry ) <<
")" );
148 std::optional<Enum> enumVal(
size_t index )
const 150 if ( index < m_mapping.size() )
152 return m_mapping[index].first;
157 size_t size()
const {
return m_mapping.size(); }
159 std::vector<std::string> labels()
const 161 std::vector<std::string> labelList;
162 for (
const auto& [ignore, label] : m_mapping )
164 labelList.push_back( label );
169 std::string label()
const {
return this->label( value() ); }
171 std::string label( Enum enumValue )
const 174 for (
const auto& [entry, entryLabel] : m_mapping )
176 if ( enumValue == entry )
185 CAFFA_ERROR(
"No value " << static_cast<int>( enumValue ) <<
" in AppEnum" );
186 for (
const auto& [entry, entryLabel] : m_mapping )
188 CAFFA_ERROR(
"Found label " << entryLabel <<
"(" << static_cast<int>( entry ) <<
")" );
190 throw std::runtime_error(
"AppEnum does not have the value " + std::to_string( static_cast<int>( enumValue ) ) );
196 size_t index( Enum enumValue )
const 198 std::optional<size_t> foundIndex;
199 for (
size_t i = 0; i < m_mapping.size(); ++i )
201 if ( m_mapping[i].first == enumValue )
208 if ( !foundIndex.has_value() )
210 CAFFA_ERROR(
"No value " << static_cast<int>( value ) <<
" in AppEnum" );
211 for (
const auto& [entry, label] : m_mapping )
213 CAFFA_ERROR(
"Found label " << label <<
"(" << static_cast<int>( entry ) <<
")" );
216 throw std::runtime_error(
"AppEnum does not have the value " + std::to_string( static_cast<int>( enumValue ) ) );
223 static bool isValid(
const std::string& label ) {
return AppEnum<Enum>().enumVal( label ).has_value(); }
224 static bool isValid(
size_t index ) {
return AppEnum<Enum>().enumval( index ).has_value(); }
227 static std::vector<std::string> validLabels() {
return AppEnum<Enum>().labels(); }
229 static size_t getIndex( Enum enumValue ) {
return AppEnum<Enum>().index( enumValue ); }
230 static std::string getLabel( Enum enumValue ) {
return AppEnum<Enum>().label( enumValue ); }
239 void addItem( Enum enumVal,
const std::string& label ) { m_mapping.push_back( std::make_pair( enumVal, label ) ); }
241 void setDefault( Enum defaultEnumValue ) { m_defaultValue = defaultEnumValue; }
243 std::optional<Enum> m_value;
244 std::optional<Enum> m_defaultValue;
246 std::vector<std::pair<Enum, std::string>> m_mapping;
249 template <
typename EnumType>
252 static std::string name()
255 std::stringstream ss;
257 for (
size_t i = 0; i < labels.size(); ++i )
259 if ( i > 0u ) ss <<
",";
271 template <
typename Enum>
277 appEnum.setFromLabel( label );
282 template <
typename Enum>
283 std::ostream& operator<<( std::ostream& str, const caffa::AppEnum<Enum>& appEnum )
285 auto value = appEnum.value();
286 str << appEnum.label( value );
std::istream & operator>>(std::istream &str, caffa::AppEnum< Enum > &appEnum)
Definition: cafAppEnum.h:272
Definition: cafPortableDataType.h:35
Definition: cafAppEnum.h:65
Main Caffa namespace.
Definition: cafApplication.h:30