How to convert an enum type variable to a string?
There really is no beautiful way of doing this. Just set up an array of strings indexed by the enum.
If you do a lot of output, you can define an operator<< that takes an enum parameter and does the lookup for you.
enum to string in modern C++11 / C++14 / C++17 and future C++20
Magic Enum header-only library provides static reflection for enums (to string, from string, iteration) for C++17.
#include <magic_enum.hpp>
enum Color { RED = 2, BLUE = 4, GREEN = 8 };
Color color = Color::RED;
auto color_name = magic_enum::enum_name(color);
// color_name -> "RED"
std::string color_name{"GREEN"};
auto color = magic_enum::enum_cast<Color>(color_name)
if (color.has_value()) {
// color.value() -> Color::GREEN
};
For more examples check home repository https://github.com/Neargye/magic_enum.
Where is the drawback?
This library uses a compiler-specific hack (based on __PRETTY_FUNCTION__
/ __FUNCSIG__
), which works on Clang >= 5, MSVC >= 15.3 and GCC >= 9.
Enum value must be in range [MAGIC_ENUM_RANGE_MIN, MAGIC_ENUM_RANGE_MAX]
.
By default
MAGIC_ENUM_RANGE_MIN = -128
,MAGIC_ENUM_RANGE_MAX = 128
.If need another range for all enum types by default, redefine the macro
MAGIC_ENUM_RANGE_MIN
andMAGIC_ENUM_RANGE_MAX
.MAGIC_ENUM_RANGE_MIN
must be less or equals than0
and must be greater thanINT16_MIN
.MAGIC_ENUM_RANGE_MAX
must be greater than0
and must be less thanINT16_MAX
.If need another range for specific enum type, add specialization enum_range for necessary enum type.
#include <magic_enum.hpp>
enum number { one = 100, two = 200, three = 300 };
namespace magic_enum {
template <>
struct enum_range<number> {
static constexpr int min = 100;
static constexpr int max = 300;
};
}
Set variable of enum type by string in TypeScript
You can use keyof typeof to convert string to enum. Below code will convert string to enum.
enum options { 'one' = 'one', 'two' = 'two', 'three' = 'three'}
let selected: options = options.one;
const newOption = "two";
console.log(selected); //prints "one"
selected = options[newOption as keyof typeof options];
// Handle if newOption is not a valid enum string
if(selected === undefined){
selected = options.three;
}
console.log(selected); //prints "two"
Typescript Playground
give an int number to enum and get its related value as string in c++
If you really can't use an array (which would be by far the easiest way), you could build a function with a switch case:
enum difficulty
{
Easy = 1,
Normal,
Hard
};
std::string diff_name(difficulty d) {
switch(d) {
case Easy: return "Easy";
case Normal: return "Normal";
case Hard: return "Hard";
default: return std::string();
}
}
And then in main
you could do
cout << "choice: ";
cin >> choice;
std::cout << "You chose: "
<< diff_name(static_cast<difficulty>(choice)) << std::endl;
Enum convert to string using compile time constants
I think it should work with MSVC2017. It uses C++14 in the constexpr functions but you can split them to single return statement constexprs to be C++11 compatible (however MSVC2017 supports C++14).
EnumConverter stores the char*, the enum and a string hash value for each enum entry. For each enum you must specialize EnumConverter::StrEnumContainer
. The enum-string pairs could be generated with a similar macro you specified.
#include <tuple>
#include <array>
#include <stdexcept>
using namespace std;
enum ELogLevel {
Info,
Warn,
Debug,
Error,
Critical
};
static constexpr size_t constexprStringHash( char const* const str ) noexcept
{
return (
( *str != 0 ) ?
( static_cast< size_t >( *str ) + 33 * constexprStringHash( str + 1 ) ) :
5381
);
}
class EnumConverter final
{
public:
EnumConverter() = delete;
EnumConverter( const EnumConverter& ) = delete;
EnumConverter( EnumConverter&& ) = delete;
EnumConverter& operator =( const EnumConverter& ) = delete;
EnumConverter& operator =( EnumConverter&& ) = delete;
template< typename ENUM_T >
static constexpr const char* toStr( const ENUM_T value )
{
const auto& strEnumArray{ StrEnumContainer< ENUM_T >::StrEnumPairs };
const char* result{ nullptr };
for( size_t index{ 0 }; index < strEnumArray.size(); ++index ) {
if( std::get< 1 >( strEnumArray[ index ] ) == value ) {
result = std::get< 0 >( strEnumArray[ index ] );
break;
}
}
return ( ( result == nullptr ) ? throw std::logic_error{ "Enum toStrBase conversion failed" } : result );
}
template< typename ENUM_T >
static constexpr ENUM_T fromStr( const char* const str )
{
const auto& strEnumArray{ StrEnumContainer< ENUM_T >::StrEnumPairs };
const size_t hash{ constexprStringHash( str ) };
const ENUM_T* result{ nullptr };
for( size_t index{ 0 }; index < strEnumArray.size(); ++index ) {
if( std::get< 2 >( strEnumArray[ index ] ) == hash ) {
result = &( std::get< 1 >( strEnumArray[ index ] ) );
}
}
return ( ( result == nullptr ) ? throw std::logic_error{ "Enum toStrBase conversion failed" } : *result );
}
private:
template< typename ENUM_T, size_t LEN >
using ARRAY_T = std::array< std::tuple< const char* const, const ENUM_T, const size_t >, LEN >;
template< typename ENUM_T >
static constexpr std::tuple< const char* const, ENUM_T, size_t > getTuple( const char* const str, const ENUM_T type ) noexcept
{
return std::tuple< const char* const, ENUM_T, size_t >{ str, type, constexprStringHash( str ) };
}
template< typename ENUM_T >
struct StrEnumContainer
{
};
template< typename ENUM_T >
friend struct StrEnumContainer;
};
template<>
struct EnumConverter::StrEnumContainer< ELogLevel >
{
using ENUM_T = ELogLevel;
static constexpr EnumConverter::ARRAY_T< ENUM_T, 5 > StrEnumPairs{ {
{ getTuple( "Info", ENUM_T::Info ) },
{ getTuple( "Warn", ENUM_T::Warn ) },
{ getTuple( "Debug", ENUM_T::Debug ) },
{ getTuple( "Error", ENUM_T::Error ) },
{ getTuple( "Critical", ENUM_T::Critical ) },
} };
};
int main()
{
//static_assert( EnumConverter::fromStr< ELogLevel >( "Info" ) == EnumConverter::fromStr< ELogLevel >( EnumConverter::toStr( Error ) ), "Error" ); // Error
static_assert(
EnumConverter::toStr( Warn )[ 0 ] == 'W' &&
EnumConverter::toStr( Warn )[ 1 ] == 'a' &&
EnumConverter::toStr( Warn )[ 2 ] == 'r' &&
EnumConverter::toStr( Warn )[ 3 ] == 'n',
"Error"
);
static_assert( EnumConverter::fromStr< ELogLevel >( "Info" ) == EnumConverter::fromStr< ELogLevel >( EnumConverter::toStr( Info ) ), "Error" );
}
How to convert enum names to string in c
One way, making the preprocessor do the work. It also ensures your enums and strings are in sync.
#define FOREACH_FRUIT(FRUIT) \
FRUIT(apple) \
FRUIT(orange) \
FRUIT(grape) \
FRUIT(banana) \
#define GENERATE_ENUM(ENUM) ENUM,
#define GENERATE_STRING(STRING) #STRING,
enum FRUIT_ENUM {
FOREACH_FRUIT(GENERATE_ENUM)
};
static const char *FRUIT_STRING[] = {
FOREACH_FRUIT(GENERATE_STRING)
};
After the preprocessor gets done, you'll have:
enum FRUIT_ENUM {
apple, orange, grape, banana,
};
static const char *FRUIT_STRING[] = {
"apple", "orange", "grape", "banana",
};
Then you could do something like:
printf("enum apple as a string: %s\n",FRUIT_STRING[apple]);
If the use case is literally just printing the enum name, add the following macros:
#define str(x) #x
#define xstr(x) str(x)
Then do:
printf("enum apple as a string: %s\n", xstr(apple));
In this case, it may seem like the two-level macro is superfluous, however, due to how stringification works in C, it is necessary in some cases. For example, let's say we want to use a #define with an enum:
#define foo apple
int main() {
printf("%s\n", str(foo));
printf("%s\n", xstr(foo));
}
The output would be:
foo
apple
This is because str will stringify the input foo rather than expand it to be apple. By using xstr the macro expansion is done first, then that result is stringified.
See Stringification for more information.
How do I convert a string to enum in TypeScript?
Enums in TypeScript 0.9 are string+number based. You should not need type assertion for simple conversions:
enum Color{
Red, Green
}
// To String
var green: string = Color[Color.Green];
// To Enum / number
var color : Color = Color[green];
Try it online
I have documention about this and other Enum patterns in my OSS book : https://basarat.gitbook.io/typescript/type-system/enums
Is there a simple way to convert C++ enum to string?
You may want to check out GCCXML.
Running GCCXML on your sample code produces:
<GCC_XML>
<Namespace id="_1" name="::" members="_3 " mangled="_Z2::"/>
<Namespace id="_2" name="std" context="_1" members="" mangled="_Z3std"/>
<Enumeration id="_3" name="MyEnum" context="_1" location="f0:1" file="f0" line="1">
<EnumValue name="FOO" init="0"/>
<EnumValue name="BAR" init="80"/>
</Enumeration>
<File id="f0" name="my_enum.h"/>
</GCC_XML>
You could use any language you prefer to pull out the Enumeration and EnumValue tags and generate your desired code.
Related Topics
C++0X Has No Semaphores? How to Synchronize Threads
Why Cast Unused Return Values to Void
How to Find the Location of the Executable in C
Compilers and Argument Order of Evaluation in C++
Can Someone Explain This Template Code That Gives Me the Size of an Array
What Is an 'Undeclared Identifier' Error and How to Fix It
Cmake Error At Cmakelists.Txt:30 (Project): No Cmake_C_Compiler Could Be Found
Is There Any Advantage of Using Map Over Unordered_Map in Case of Trivial Keys
When to Use Dynamic Vs. Static Libraries
Will Std::String Always Be Null-Terminated in C++11
Position of Least Significant Bit That Is Set
Difference Between Static and Dynamic Arrays in C++
How to "Return an Object" in C++
Accessing Class Members on a Null Pointer
C++: What Is the Size of an Object of an Empty Class
How to Make a Fully Statically Linked .Exe With Visual Studio Express 2005