
Hey, Please have a look at the thread on boost.users called "safe assign of int to enum" and let me know if there is any interest here in the library I describe. (I didn't want to cross-post) Any suggestions/feature requests will be gratefully accepted. TIA, Tom

On 3/27/06, Tomas Puverle <Tomas.Puverle@morganstanley.com> wrote:
Hey,
Please have a look at the thread on boost.users called "safe assign of int to enum" and let me know if there is any interest here in the library I describe. (I didn't want to cross-post) Any suggestions/feature requests will be gratefully accepted. TIA,
I'm interested
Tom
-- Felipe Magno de Almeida

Tomas Puverle wrote:
Hey,
Please have a look at the thread on boost.users called "safe assign of int to enum" and let me know if there is any interest here in the library I describe. (I didn't want to cross-post) Any suggestions/feature requests will be gratefully accepted. TIA,
Yes, I'm interested. Here is my wish list: 1. only the meta information that is really used should end up in the executable (can be done via template instantiations) 2. use a more intuitive name than "smart enum" something like "reflective enum" or so 3. the implementation should store the values in a structure like that struct enum_name { enum type { [... values ...] }; private: // [...friend declaration & accessors for meta information...] }; 3.1. the storage type should be a real enum 3.2. its name should be "type" so the enclosing structure can act as a metafunction 3.3. no public members, access is implemented via freestanding functions Regards, Tobias

Tobias, Thank you for your email. Please see my comments inline.
1. only the meta information that is really used should end up in the executable (can be done via template instantiations)
I am in the process of completely rewriting the library to make it more boost- like, as well as adding some of the features on my wish list and to make it more robust and configurable. The idea is to do what you describe. The enum is policy driven and allows you configure the features you want/need. For example, you can disable/enable the string to enum functionality, configure the internal representation etc.
2. use a more intuitive name than "smart enum" something like "reflective enum" or so
I quite like the name "smart_enum" but if there is a negative response to the name I will change it. I hope you don't mind me saying so but I don't like "reflective_enum" much. Perhaps we can find a compromise?
3. the implementation should store the values in a structure like that
struct enum_name { enum type { [... values ...] }; private: // [...friend declaration & accessors for meta information...] };
This is exactly what my original implementation did as I prefer that practice, too. However, I realised that there are people out there that would perhaps like to use this facility but don't want to/can't to go throught all of their code and change all of the uses of unqualified enum names to qualified ones. My rewrite provides a facility to create both "free" and "wrapped" enums.
3.1. the storage type should be a real enum
3.2. its name should be "type" so the enclosing structure can act as a
Yes, unless the user specifies otherwise. The user can override the base size of the enum, to e.g. facilitate binary compatibility between shared libraries. (but this is compile time checked to ensure values will fit). In some rare cases, if using some of the features of the enum you may also end up with an integer larger than the one needed just to hold the enum values but again, this is all user controled. The basic point is that the internal representation is always just an integer. In fact, you can configure the enum to actually use storage smaller than may be required to store the actual enum ;) Probably not very useful but the feature just kind of falls out of the design so I allow you to enable it. metafunction Yes, the internal name is called type. But I have more than that. You can e.g. use the enum as an mpl bidirectional sequence, so you can traverse it at compile time.
3.3. no public members, access is implemented via freestanding functions
There are some public members which I believe are generally useful. I thought about this and was undecided between the two approaches: members of free functions? In the end I decided on providing both. You can then take your pick. Thanks for the suggestions. I should be able to post something soon. Tom

Tomas Puverle wrote:
I am in the process of completely rewriting the library to make it more boost- like,
Are you aware of the BOOST_ENUM_VALUES in the file vault? It's pretty advanced. The file is called enum_rev4.6.zip If you both have a lot of energy, I suggest that you team up to get this ready for a review. -Thorsten

Tomas Puverle wrote:
Thank you for your email.
You're welcome! This idea is worth commenting on -- I'm sure that such a utility can be broadly useful (I'd certainly like to have it in my toolbox ;-) ).
1. only the meta information that is really used should end up in the
executable
(can be done via template instantiations)
I am in the process of completely rewriting the library to make it more boost- like, as well as adding some of the features on my wish list and to make it more robust and configurable. The idea is to do what you describe. The enum is policy driven and allows you configure the features you want/need. For example, you can disable/enable the string to enum functionality, configure the internal representation etc.
Actually I was not talking about ability to customize things but rather about putting the meta information into templates (so there is no overhead when there are no instantiations). Why write policies for things that can work automatically?
2. use a more intuitive name than "smart enum" something like "reflective enum" or so
I quite like the name "smart_enum" but if there is a negative response to the name I will change it. I hope you don't mind me saying so but I don't like "reflective_enum" much. Perhaps we can find a compromise?
The problem I have with "smart" is that it doesn't really say anything... I actually like "managed" (even though that adjective might sound .NETish).
3. the implementation should store the values in a structure like that
struct enum_name { enum type { [... values ...] }; private: // [...friend declaration & accessors for meta information...] };
This is exactly what my original implementation did as I prefer that practice, too. However, I realised that there are people out there that would perhaps like to use this facility but don't want to/can't to go throught all of their code and change all of the uses of unqualified enum names to qualified ones. My rewrite provides a facility to create both "free" and "wrapped" enums.
OK - so my code is what you call a "wrapped" enum then, I figure...
3.3. no public members, access is implemented via freestanding functions
There are some public members which I believe are generally useful. I thought about this and was undecided between the two approaches: members of free functions? In the end I decided on providing both. You can then take your pick.
...and "free" enums can't have member functions, right? If so, it's a very strong argument against a public member function interface -- maybe even against member functions and wrapped enums (let the user wrap it at will) altogether.
3.2. its name should be "type" so the enclosing structure can act as a metafunction
Yes, the internal name is called type. But I have more than that. You can e.g. use the enum as an mpl bidirectional sequence, so you can traverse it at compile time.
BOOST_FOREACH(my_enum) (or BOOST_FOREACH(mpl_sequence_of_constants) for that matter) would be cool... However, this feature would require a detection mechanism to find out whether some tokens represent a type or an expression -- and I don't know if it's implementable without a (native) typeof operator. struct normalize { template<typename T> normalize(T const &); }; #define IS_TYPE(parenthesized_input) \ ::boost::is_function< typeof(normalize parenthesized_input) > // IS_TYPE((int))::value is true // IS_TYPE((1))::value is false Does anyone know how to implement this without a typeof operator? 4. Another idea: hanlde ORed combinations of enumerators that encode bit patterns (probably even with constraints)... Regards, Tobias

"Tobias Schwinger" wrote
// IS_TYPE((int))::value is true // IS_TYPE((1))::value is false
Does anyone know how to implement this without a typeof operator?
I havent got a solution but one avenue thats seems to be in the right field is to exploit the difference between a function call and a declaration: Sometype func_or_value( Entity_to_test); eg assume Entity_to_test is a type then func_or_value is a function, else func_or_value is a variable. Dont know if it helps though. The other slim hope is exploiting how e.g std::for_each uses its last argument, but I dont quite know how that would help if at all. regards Andy Little

"Andy Little" wrote
"Tobias Schwinger" wrote
// IS_TYPE((int))::value is true // IS_TYPE((1))::value is false
Does anyone know how to implement this without a typeof operator?
I havent got a solution but one avenue thats seems to be in the right field is to exploit the difference between a function call and a declaration:
Sometype func_or_value( Entity_to_test);
eg assume Entity_to_test is a type then func_or_value is a function, else func_or_value is a variable.
The following seems to work in VC7.1 though it declares a variable if T is a value: ------------- #include <boost/preprocessor/cat.hpp> #include <boost/typeof/typeof.hpp> #include <boost/type_traits/remove_pointer.hpp> #include <boost/type_traits/is_function.hpp> #include <iostream> // necessary for the return/decl type of VARIABLE_OR_TYPE(T) struct SomeType{ // SomeType must have a unconstrained value ctor template <typename T> SomeType( T const &){}; }; #define VARIABLE_OR_TYPE(T) \ SomeType BOOST_PP_CAT(var_or_func,T)(T); // test VARIABLE_OR_TYPE(int); VARIABLE_OR_TYPE(1); int main() { // these would need to be wrapped in the macro I guess... // var_or_funcint is the decl from VARIABLE_OR_TYPE(int); typedef BOOST_TYPEOF(&var_or_funcint) tt; std::cout << boost::is_function<boost::remove_pointer<tt>::type >::value <<'\n'; // var_or_func1 is the decl from VARIABLE_OR_TYPE(1); typedef BOOST_TYPEOF(&var_or_func1) t1; std::cout << boost::is_function<boost::remove_pointer<t1>::type >::value <<'\n'; } regards Andy Little

Andy Little wrote:
"Tobias Schwinger" wrote
// IS_TYPE((int))::value is true // IS_TYPE((1))::value is false
Does anyone know how to implement this without a typeof operator?
I havent got a solution but one avenue thats seems to be in the right field is to exploit the difference between a function call and a declaration:
Sometype func_or_value( Entity_to_test);
eg assume Entity_to_test is a type then func_or_value is a function, else func_or_value is a variable.
Yeah, this route occured to me. Unfortunately it requires namespace or class scope to work, while the typeof version can be encoded in a single expression.
Dont know if it helps though. The other slim hope is exploiting how e.g std::for_each uses its last argument, but I dont quite know how that would help if at all.
I'm not sure I know what you mean. Would you elaborate? Regards, Tobias
participants (5)
-
Andy Little
-
Felipe Magno de Almeida
-
Thorsten Ottosen
-
Tobias Schwinger
-
Tomas Puverle