Smart enum

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
9 messages Options
Reply | Threaded
Open this post in threaded view
|

Smart enum

Tomas Puverle
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

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: Smart enum

Felipe Magno de Almeida
On 3/27/06, Tomas Puverle <[hidden email]> 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
_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: Smart enum

Tobias Schwinger
In reply to this post by Tomas Puverle
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

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: Smart enum

Tomas Puverle
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

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.

> 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.

> 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

















_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: Smart enum

thorsten.ottosen
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
_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: Smart enum

Tobias Schwinger
In reply to this post by Tomas Puverle
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

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: Smart enum

Andy Little
"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








_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: Smart enum

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


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: Smart enum

Tobias Schwinger
In reply to this post by 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

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost