strongly enum to integer and vice-versa - c++

Here is my source (as answer) , how to implement underlying_value, and to_enum functions.
How to automatically convert strongly typed enum into int?
underlying_value - no problem.
but, to_enum - has problem.
see:
enum class E{ a = 1, b = 3, c = 5 };
auto e_a = utils::underlying_value(E::a); //OK
E t = utils::to_enum<E>( 2 ) ; // compiled, but it's incorrect. I think here must throws exception?
Q: how to implement to_enum correctly?

Despite the comments on the question, this can be done in C++11, though to do it without code repetition you will eventually have to wrap the enum class declaration in a macro. That may make my answer unsuitable, depending on your needs. Either way, doing the checked conversion requires some machinery, so I will get to the macro last.
The basic idea is to use constexpr functions to scan an array:
#include <iostream>
#include <stdexcept>
enum class E { a = 1, b = 3, c = 5 };
constexpr E values[] = {E::a, E::b, E::c};
constexpr size_t count = sizeof(values) / sizeof(E);
constexpr E to_enum(int value, size_t index = 0)
{
return
index >= count ? throw std::runtime_error("invalid integer") :
static_cast<int>(values[index]) == value ? values[index] :
to_enum(value, index + 1);
}
constexpr E converted = to_enum(3);
// Will not compile if uncommented.
// constexpr E bad_converted = to_enum(2);
int main()
{
std::cout << static_cast<int>(converted) << std::endl;
return 0;
}
This prints 3. If the line with bad_converted is uncommented, this code will not compile at all, as it says. The checked conversion can be done either at runtime or during compilation. It will be done during compilation if the argument to to_enum is a compile-time constant. Also, as you can probably see, this does a linear scan of values, but that can be replaced with another algorithm if it becomes a performance problem for a very large enum.
The code I just showed is a sketch that shows the underlying method. In order to make this less of a pain to use, you should wrap the declaration of E in a macro that will automatically generate the values[] array and the associated functions. I will show and rationalize the contents of this macro one point at a time.
The basic macro looks like this
// Declaration header
#define ENUM_CLASS(TypeName, __VA_ARGS__)
// Use
ENUM_CLASS(E, a = 1, b = 3, c = 5);
So, in this example, __VA_ARGS__ will be the tokens a = 1, b = 3, c = 5. So, we can declare the enum itself inside the macro as follows:
enum class TypeName { __VA_ARGS__ };
However, we cannot simply declare:
constexpr TypeName values[] = { __VA_ARGS__ };
because that expands to
constexpr TypeName values[] = { a = 1, b = 3, c = 5 };
which is not scoped (missing TypeName:: in front of each value), and is not valid C++ because of the extra assignment operators inside the array initializer. I will solve the second problem first. You need to define a class like this one:
template <typename E>
class swallow_assignment {
public:
E _value;
constexpr explicit swallow_assignment(E value) : _value(value)
{
}
template <typename Any>
constexpr const swallow_assignment& operator =(Any other) const
{
return *this;
}
constexpr operator E() const
{
return _value;
}
};
Now, you can write (swallow_assignment<E>)E::a = 1. What will happen is, at compile time, E::a will get converted to the assignable value (swallow_assignment<E>)E::a, which has the same internal representation as E::a. That value will then ignore the assignment of 1, and then will be converted back to E::a.
What's left is to prefix each of the declared constants so that we get
constexpr TypeName values[] =
{(swallow_assignment<E>)E::a = 1,
(swallow_assignment<E>)E::b = 3,
(swallow_assignment<E>)E::c = 5})
which will now be a valid initializer. This can be done with a mapping macro. I won't go into the details here, because that is a whole separate topic, but such a macro can be found here https://github.com/aantron/better-enums/blob/e28177b11a9e3d7152c5216d84fdf8939aff0eba/enum_preprocessor_map.h. Boost might also have a better one. Whatever macro you are using, I will assume that its signature is PP_MAP(prefix, __VA_ARGS__). The sketch for the final macro definition for the whole enum then becomes:
#define ENUM_CLASS(TypeName, __VA_ARGS__) \
enum class TypeName { __VA_ARGS__ }; \
constexpr TypeName values[] = \
{ PP_MAP((swallow_assignment<TypeName>)TypeName::, \
__VA_ARGS__) }; \
constexpr size_t count = sizeof(values) / sizeof(TypeName);
You will probably want to stuff these definitions into a specialization of a traits type, so that you can use this macro with more than one enum class (otherwise the arrays named values will collide). You may have to use weak symbols to avoid linking problems if you make values a static member of a traits class, however.
These last points are left as an exercise, because this answer is already way too long :) I have a library which does all of the above, though it wraps an enum instead of providing a traits specialization for an enum class. There is an unpublished branch with a combination of enum class/traits, however. You can see the library here: http://aantron.github.io/better-enums. The library's ::_from_integral() method corresponds to the to_enum function in your question, and it does both run-time and compile-time conversions.

Related

Building data structures at compile time with template-metaprogramming, constexpr or macros

I want to optimize a little programm/library i'm writing and since 2 weeks i'm somewhat stuck and now wondering if what i had in mind is even possible like that.
(Please be gentle i don't have very much experience in meta-programming.)
My goal is of course to have certain computations be done by the compiler, so that the programmer - hopefully - only has to edit code at one point in the program and have the compiler "create" all the boilerplate. I do have a resonably good idea how to do what i want with macros, but it is wished that i do it with templates if possible.
My goal is:
Lets say i have a class that a using programmer can derive from. There he can have multiple incoming and outgoing datatypes that i want to register somehow so that the base class can do i'ts operations on them.
class my_own_multiply : function_base {
in<int> a;
in<float> b;
out<double> c;
// ["..."] // other content of the class that actually does something but is irrelevant
register_ins<a, b> ins_of_function; // example meta-function calls
register_outs<c> outs_of_function;
}
The meta-code i have up till now is this: (but it's not jet working/complete)
template <typename... Ts>
struct register_ins {
const std::array<std::unique_ptr<in_type_erasured>, sizeof...(Ts)> ins;
constexpr std::array<std::unique_ptr<in_type_erasured>, sizeof...(Ts)>
build_ins_array() {
std::array<std::unique_ptr<in_type_erasured>, sizeof...(Ts)> ins_build;
for (unsigned int i = 0; i < sizeof...(Ts); ++i) {
ins_build[i] = std::make_unique<in_type_erasured>();
}
return ins_build;
}
constexpr register_ins() : ins(build_ins_array()) {
}
template <typename T>
T getValueOf(unsigned int in_nr) {
return ins[in_nr]->getValue();
}
};
As you may see, i want to call my meta-template-code with a variable number of ins. (Variable in the sens that the programmer can put however many he likes in there, but they won't change at runtime so they can be "baked" in at compile time)
The meta-code is supposed to be creating an array, that is of the lengt of the number of ins and is initialized so that every field points to the original in in the my_own_multiply class. Basically giving him an indexable data structure that will always have the correct size. And that i could access from the function_base class to use all ins for certain functions wich are also iterable making things convinient for me.
Now i have looked into how one might do that, but i now am getting the feeling that i might not really be allowed to "create" this array at compile time in a fashion that allows me to still have the ins a and b be non static and non const so that i can mutate them. From my side they wouldn't have to be const anyway, but my compliler seems to not like them to be free. The only thing i need const is the array with the pointers. But using constexpr possibly "makes" me make them const?
Okay, i will clarify what i don't get:
When i'm trying to create an "instance" of my meta-stuff-structure then it fails because it expects all kinds of const, constexpr and so on. But i don't want them since i need to be able to mutate most of those variables. I only need this meta-stuff to create an array of the correct size already at compile time. But i don't want to sacrifice having to make everything static and const in order to achive this. So is this even possible under these kinds of terms?
I do not get all the things you have in mind (also regarding that std::unique_ptr in your example), but maybe this helps:
Starting from C++14 (or C++11, but that is strictly limited) you may write constexpr functions which can be evaluated at compile-time. As a precondition (in simple words), all arguments "passed by the caller" must be constexpr. If you want to enforce that the compiler replaces that "call" by the result of a compile-time computation, you must assign the result to a constexpr.
Writing usual functions (just with constexpr added) allows to write code which is simple to read. Moreover, you can use the same code for both: compile-time computations and run-time computations.
C++17 example (similar things are possible in C++14, although some stuff from std is just missing the constexpr qualifier):
http://coliru.stacked-crooked.com/a/154e2dfcc41fb6c7
#include <cassert>
#include <array>
template<class T, std::size_t N>
constexpr std::array<T, N> multiply(
const std::array<T, N>& a,
const std::array<T, N>& b
) {
// may be evaluated in `constexpr` or in non-`constexpr` context
// ... in simple man's words this means:
// inside this function, `a` and `b` are not `constexpr`
// but the return can be used as `constexpr` if all arguments are `constexpr` for the "caller"
std::array<T, N> ret{};
for(size_t n=0; n<N; ++n) ret[n] = a[n] * b[n];
return ret;
}
int main() {
{// compile-time evaluation is possible if the input data is `constexpr`
constexpr auto a = std::array{2, 4, 6};
constexpr auto b = std::array{1, 2, 3};
constexpr auto c = multiply(a, b);// assigning to a `constexpr` guarantees compile-time evaluation
static_assert(c[0] == 2);
static_assert(c[1] == 8);
static_assert(c[2] == 18);
}
{// for run-time data, the same function can be used
auto a = std::array{2, 4, 6};
auto b = std::array{1, 2, 3};
auto c = multiply(a, b);
assert(c[0] == 2);
assert(c[1] == 8);
assert(c[2] == 18);
}
return 0;
}

Getting all values from an enum

I have classes in the style of Class1 (see code). An enum and a function to get all the values from the enum. The values (FOO_1, FOO_2 etc) differ from Class to Class as well as the number of values (sizeof(Foos)).
I call the function once to get the sizeof the enum, reserve memory and with the second call I want to get all the values to *pFoos (2,1,6 in the sample code).
Is there a better way then using an array with all the values in it (size_t arr[3] ={FOO_1 , FOO_X, FOO_BAR })?
class Class1{
enum Foos{
FOO_1 = 2,
FOO_X = 1,
FOO_BAR = 6
}
};
Class1::GetFoos(size_t* pFoos, size_t* pSize)
{
size_t len = sizeof(Foos);
if (len > *pSize)
{ //Call function once to get the size
*pSize= len ;
return -1;
}
for(size_t i = 0; i< *pSize; i++)
{
//copy all enum values to pFoos
}
};
Disclaimer: shameless plug – I am the author.
Reflective enums are possible in C++. I wrote a header-only library that captures a bunch of "patterns" at compile time and gives you syntax like this:
ENUM(Class1, int, FOO_1 = 2, FOO_X = 1, FOO_BAR = 6)
size_t count = Class1::_size;
for (size_t index = 0; index < Class1::_size; ++index)
do_anything(Class1::_values()[index]);
What it does internally is use the macro to generate an array of the values that you have declared, kind of like in your question, and use a bunch of other tricks to allow you to use initializers naturally. It then provides iterators and other things on top of the array.
Here is a link: https://github.com/aantron/better-enums
EDIT – internals
Here is a pseudocode sketch of what it does internally. The reason I am only giving a "sketch" is because there are a bunch of issues to consider when doing this portably. I will touch on all the most important elements.
ENUM(Class1, int, FOO_1 = 2, FOO_X = 1, FOO_BAR = 6)
notionally expands to
struct Class1 {
enum _enumerated { FOO_1 = 2, FOO_X = 1, FOO_BAR = 6 };
// Fairly obvious methods for how to iterate over _values and
// _names go here. Iterators are simply pointers into _values
// and _names below.
static size_t _size = sizeof(_values) / sizeof(int);
int _value;
};
int _values[] = {(fix_t<Class1>)Class1::FOO_1 = 2,
(fix_t<Class1>)Class1::FOO_X = 1,
(fix_t<Class1>)Class1::FOO_BAR = 6};
const char *_names[] = {"FOO_1 = 2", "FOO_X = 1", "FOO_BAR = 6"};
This is done by using variadic macros and stringization. The methods that deal with strings treat not only \0, but also space and equals as terminators, which allows them to ignore the initializers in the stringized constants that you see in _names.
The type fix_t is necessary because having assignments inside an array initializer is not valid C++. What that type does is take on the value of the enum, then ignore the assignment by an overloaded assignment operator, and then return the original value. A sketch:
template <typename Enum>
struct fix_t {
Enum _value;
fix_t(Enum value) : _value(value) { }
const fix_t& operator =(int anything) const { return *this; }
operator Enum() const { return _value; }
};
This makes the _values array possible declare even in the presence of initializers.
Of course, these arrays need to be prefixed so that you can have more than one enum like this. They also need to have the same as "extern inline" linkage for functions, so that they are shared between multiple compilation units.
Until c++ will get reflection you will not get any data from your enum! Simply you can not get "all" values from an enum. A enum is simply a kind of namespace where some constants can be defined and may be enumerated automatically. Not more at all. You have no text representation, no count information, no value to text information!
Is there a better way then using an array with all the values in it (size_t arr[3] ={FOO_1 , FOO_X, FOO_BAR })?
If you're tagging the question as C++ I advise you to give up with the C way of doing things, so the better way to do this in C++ is using a std::vector:
class Class1{
enum Foos{
FOO_1 = 2,
FOO_X = 1,
FOO_BAR = 6
};
public:
std::vector<int> GetFoos()
{
// return all enum values
return {FOO_1, FOO_X, FOO_BAR};
}
};
You can use it this way:
Class1 c1;
auto foos = c1.GetFoos();
std::cout << "I have " << c1.size() << " foos:\n";
for (const auto &foo : foos) std::cout << foo << '\n';
If you don't want to create the vector at runtime, you can create it once declaring it static:
class Alpha{
enum Alphas{
BETA = 0b101010,
GAMMA = 0x20,
EPSILON = 050
};
static const std::vector<int> m_alphas;
public:
const std::vector<int> &GetAlphas()
{
return m_alphas;
}
};
// https://isocpp.org/wiki/faq/ctors#explicit-define-static-data-mems
const std::vector<int> Alpha::m_alphas = {BETA, GAMMA, EPSILON};
Live demo
I know that is a burden to maintain but since there's no way to iterate the values of an enum, all the code that tries to iterate them is a burden as well.
Maybe in the following answer you can find something useful to iterate enums in a better way for your goals:
enum to string in modern C++ and future C++17.

Equivalent of .values() of enum from Java in C++

I first initially learnt to program in Java and therefore when working with enums, I could use .values() in order to produce an array of all the values in that specific enum. I've noticed that now learning C++, there is not an equivalent method.
What is the best way to tackle this as I'm sure people have come up with decent workarounds?
Doing this in C++ usually requires a special sentinel value inside the enumeration or some preprocessor magic.
If your enumerators are sequential then you can use a simple sentinel value (end in this case):
enum my_enum {
a,
b,
c,
my_enum_end,
};
for (int i = 0; my_enum_end != i; ++i) {
// Loop through all of the enum values.
}
When the enumeration is more complicated and there are gaps between each of the enumerators then you can use the preprocessor:
#define ENUMS(F) F(a, 1) F(b, 5) F(c, 10)
#define AS_ENUM(ID, V) ID = V,
#define AS_VALUE(ID, V) V,
#define AS_ID(ID, V) #ID,
enum my_enum {
ENUMS(AS_ENUM)
};
my_enum const my_enum_values[] = {ENUMS(AS_VALUE)};
std::string const my_enum_keys[] = {ENUMS(AS_ID)};
for (my_enum const i : my_enum_values) {
// Loop through all of the enum values.
}
for (auto const& i : my_enum_keys) {
// Loop through all of the enum keys.
}
Here all of the enumerators are specified in the ENUMS macro rather than inside the enum definition directly.

Populate An Array Using Constexpr at Compile-time

I would like to populate an array of enum using constexpr.
The content of the array follows a certain pattern.
I have an enum separating ASCII character set into four categories.
enum Type {
Alphabet,
Number,
Symbol,
Other,
};
constexpr Type table[128] = /* blah blah */;
I would like to have an array of 128 Type. They can be in a structure.
The index of the array will be corresponding to the ASCII characters and the value will be the Type of each character.
So I can query this array to find out which category an ASCII character belongs to. Something like
char c = RandomFunction();
if (table[c] == Alphabet)
DoSomething();
I would like to know if this is possible without some lengthy macro hacks.
Currently, I initialize the table by doing the following.
constexpr bool IsAlphabet (char c) {
return ((c >= 0x41 && c <= 0x5A) ||
(c >= 0x61 && c <= 0x7A));
}
constexpr bool IsNumber (char c) { /* blah blah */ }
constexpr bool IsSymbol (char c) { /* blah blah */ }
constexpr Type whichCategory (char c) { /* blah blah */ }
constexpr Type table[128] = { INITIALIZE };
where INITIALIZE is the entry point of some very lengthy macro hacks.
Something like
#define INITIALIZE INIT(0)
#define INIT(N) INIT_##N
#define INIT_0 whichCategory(0), INIT_1
#define INIT_1 whichCategory(1), INIT_2
//...
#define INIT_127 whichCategory(127)
I would like a way to populate this array or a structure containing the array without the need for this macro hack...
Maybe something like
struct Table {
Type _[128];
};
constexpr Table table = MagicFunction();
So, the question is how to write this MagicFunction?
Note: I am aware of cctype and likes, this question is more of a Is this possible? rather than Is this the best way to do it?.
Any help would be appreciated.
Thanks,
Ignoring ALL the issues, indices to the rescue:
template<unsigned... Is> struct seq{};
template<unsigned N, unsigned... Is>
struct gen_seq : gen_seq<N-1, N-1, Is...>{};
template<unsigned... Is>
struct gen_seq<0, Is...> : seq<Is...>{};
template<unsigned... Is>
constexpr Table MagicFunction(seq<Is...>){
return {{ whichCategory(Is)... }};
}
constexpr Table MagicFunction(){
return MagicFunction(gen_seq<128>{});
}
Live example.
In C++17 ::std::array has been updated to be more constexpr friendly and you can do the same as in C++14, but without some of the scary looking hacks to get around the lack of constexpr in crucial places. Here is what the code would look like there:
#include <array>
enum Type {
Alphabet,
Number,
Symbol,
Other,
};
constexpr ::std::array<Type, 128> MagicFunction()
{
using result_t = ::std::array<Type, 128>;
result_t result = {Other};
result[65] = Alphabet;
//....
return result;
}
const ::std::array<Type, 128> table = MagicFunction();
Again MagicFunction still needs to obey the rather loose constexpr rules. Mainly, it may not modify any global variables or use new (which implies modifying global state, namely the heap) or other such things.
IMHO the best way to do this is simply write a tiny setup program that will generate table for you. And then you can either throw out the setup program, or check it in alongside the generated source code.
The tricky part of this question is just a duplicate of this other one: Is it possible to create and initialize an array of values using template metaprogramming?
The trick is, it's impossible to write anything like
Type table[256] = some_expression();
at file scope, because global arrays can be initialized only with literal (source-level) initializer-lists. You can't initialize a global array with the result of a constexpr function, even if you could somehow get that function to return a std::initializer_list, which you can't because its constructor isn't declared constexpr.
So what you have to do is get the compiler to generate the array for you, by making it a static const data member of a template class. After one or two levels of metaprogramming that I'm too confused to write out, you'll bottom out in a line that looks something like
template <int... Indices>
Type DummyStruct<Indices...>::table[] = { whichCategory(Indices)... };
where Indices is a parameter-pack that looks like 0,1,2,... 254,255. You construct that parameter-pack using a recursive helper template, or maybe just using something out of Boost. And then you can write
constexpr Type (&table)[] = IndexHelperTemplate<256>::table;
...But why would you do all that, when the table is only 256 entries that will never change unless ASCII itself changes? The right way is the simplest way: precompute all 256 entries and write out the table explicitly, with no templates, constexpr, or any other magic.
The way to do this in C++14 looks like this:
#include <array>
enum Type {
Alphabet,
Number,
Symbol,
Other,
};
constexpr ::std::array<Type, 128> MagicFunction()
{
using result_t = ::std::array<Type, 128>;
result_t result = {Other};
const result_t &fake_const_result = result;
const_cast<result_t::reference>(fake_const_result[65]) = Alphabet;
//....
return result;
}
const ::std::array<Type, 128> table = MagicFunction();
No clever template hackery required any longer. Though, because C++14 didn't really undergo a thorough enough review of what did and didn't have to be constexpr in the standard library, a horrible hack involving const_cast has to be used.
And, of course, MagicFunction had better not modify any global variables or otherwise violate the constexpr rules. But those rules are pretty liberal nowadays. You can, for example, modify all the local variables you want, though passing them by reference or taking their addresses may not work out so well.
See my other answer for C++17, which allows you to drop some of the ugly-looking hacks.

How can the allowed range of an integer be restricted with compile time errors?

I would like to create a type that is an integer value, but with a restricted range.
Attempting to create an instance of this type with a value outside the allowable range should cause a compile time error.
I have found examples that allow compile time errors to be triggered when an enumeration value outside those specified is used, but none that allow a restricted range of integers (without names).
Is this possible?
Yes but it's clunky:
// Defining as template but the main class can have the range hard-coded
template <int Min, int Max>
class limited_int {
private:
limited_int(int i) : value_(i) {}
int value_;
public:
template <int Val> // This needs to be a template for compile time errors
static limited_int make_limited() {
static_assert(Val >= Min && Val <= Max, "Bad! Bad value.");
// If you don't have static_assert upgrade your compiler or use:
//typedef char assert_in_range[Val >= Min && Val <= Max];
return Val;
}
int value() const { return value_; }
};
typedef limited_int<0, 9> digit;
int main(int argc, const char**)
{
// Error can't create directly (ctor is private)
//digit d0 = 5;
// OK
digit d1 = digit::make_limited<5>();
// Compilation error, out of range (can't create zero sized array)
//digit d2 = digit::make_limited<10>();
// Error, can't determine at compile time if argc is in range
//digit d3 = digit::make_limited<argc>();
}
Things will be much easier when C++0x is out with constexpr, static_assert and user defined literals.
Might be able to do something similar by combining macros and C++0x's static assert.
#define SET_CHECK(a,b) { static_assert(b>3 && b<7); a=b; }
A runtime integer's value can only be checked at runtime, since it only exists at runtime, but if you make a runtime check on all writing methods, you can guarantee it's contents. You can build a regular integral replacement class with given restrictions for that.
For constant integers, you could use a template to enforce such a thing.
template<bool cond, typename truetype> struct enable_if {
};
template<typename truetype> struct enable_if<true, truetype> {
typedef truetype type;
};
class RestrictedInt {
int value;
RestrictedInt(int N)
: value(N) {
}
public:
template<int N> static typename enable_if< (N > lowerbound) && (N < upperbound), RestrictedInt>::type Create() {
return RestrictedInt(N);
}
};
Attempting to create this class with a template value that isn't within the range will cause a substitution failure and a compile-time error. Of course, it will still require adornment with operators et al to replace int, and if you want to compile-time guarantee other operations, you will have to provide static functions for them (there are easier ways to guarantee compile-time arithmetic).
Well, as you noticed, there is already a form of diagnostic for enumerations.
It's generally crude: ie the checking is "loose", but could provide a crude form of check as well.
enum Range { Min = 0, Max = 31 };
You can generally assign (without complaint) any values between the minimal and maximal values defined.
You can in fact often assign a bit more (I think gcc works with powers of 2).