
Hi all, Say I have a compile-time map of <value,type> pairs, and I need to access the correct element given a value at runtime and do something with that type. That something would be the same for any of the mapped types (e.g. calling an overloaded function that would then do the right thing depending on the type). The value would typically be an enum. Is there anything in the Boost libraries to help with this? If I used C++11, would there be a simple solution to this? Regards PS: I cannot use Boost.Variant

On July 31, 2015 6:01:04 AM EDT, dariomt@gmail.com wrote:
Hi all,
Say I have a compile-time map of <value,type> pairs, and I need to access the correct element given a value at runtime and do something with that type. That something would be the same for any of the mapped types (e.g. calling an overloaded function that would then do the right thing depending on the type).
The value would typically be an enum.
Is there anything in the Boost libraries to help with this?
If I used C++11, would there be a simple solution to this?
Not really a boost question, perhaps. First, I'm not sure why anyone wouldn't leverage at least C++11+. Especially considering compiler advancements in recent history. Optimization technology being what it is and all. That said, if it was me, I might have a look at a std::function (or boost::function) "type factory" that knew how to interface with an instance repository. Could be a functor instance, as well, for that matter.
Regards
Cheers.
PS: I cannot use Boost.Variant
Why not?
------------------------------------------------------------------------
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
-- Sent from my Android device with K-9 Mail. Please excuse my brevity.

Michael <mwpowellhtx <at> gmail.com> writes:
On July 31, 2015 6:01:04 AM EDT, dariomt <at> gmail.com wrote:
Hi all,
Say I have a compile-time map of <value,type> pairs, and I need to access the correct element given a value at runtime and do something with
that
type. That something would be the same for any of the mapped types (e.g. calling an overloaded function that would then do the right thing depending on the type).
The value would typically be an enum.
Is there anything in the Boost libraries to help with this?
If I used C++11, would there be a simple solution to this?
Not really a boost question, perhaps. I thought asking if Boost has tools to help with certain C++ problem was allowed in this list. Please correct me if I'm wrong.
First, I'm not sure why anyone wouldn't leverage at least C++11+.
Especially considering compiler
advancements in recent history. Optimization technology being what it is and all.
I'd rather use a well tested Boost component than a C++11 solution I have to implement, test and document.
That said, if it was me, I might have a look at a std::function (or boost::function) "type factory" that knew how to interface with an instance repository.
Could be a functor instance, as well, for that matter.
Regards
Cheers.
PS: I cannot use Boost.Variant
Why not?
Sorry, it is clear I didn't explain my problem well enough. Say I have this code. struct A {}; struct B {}; enum useType {useA, useB}; template <typename F> void g(useType w, F f) { switch (w) { case useA: A a; f(a); case useB: B b; f(b); } } I need to generalize this to any number of enum values and any number of corresponding types. Something like this (pseudocode): typedef compile_time_map< mpl::pair<useA,A>, mpl::pair<useB,B>, ... > mapping; template <typename F> void g(useType w, F f) { switch_apply( w, mapping, f ); }

On 31.07.2015 15:10, dariomt wrote:
Michael <mwpowellhtx <at> gmail.com> writes:
On July 31, 2015 6:01:04 AM EDT, dariomt <at> gmail.com wrote:
Hi all,
Say I have a compile-time map of <value,type> pairs, and I need to access the correct element given a value at runtime and do something with
that
type. That something would be the same for any of the mapped types (e.g. calling an overloaded function that would then do the right thing depending on the type).
The value would typically be an enum.
Is there anything in the Boost libraries to help with this?
If I used C++11, would there be a simple solution to this? Not really a boost question, perhaps. I thought asking if Boost has tools to help with certain C++ problem was allowed in this list. Please correct me if I'm wrong.
First, I'm not sure why anyone wouldn't leverage at least C++11+. Especially considering compiler advancements in recent history. Optimization technology being what it is and all. I'd rather use a well tested Boost component than a C++11 solution I have to implement, test and document.
That said, if it was me, I might have a look at a std::function (or boost::function) "type factory" that knew how to interface with an instance repository.
Could be a functor instance, as well, for that matter.
Regards Cheers.
PS: I cannot use Boost.Variant Why not?
Sorry, it is clear I didn't explain my problem well enough.
Say I have this code. struct A {}; struct B {}; enum useType {useA, useB};
template <typename F> void g(useType w, F f) { switch (w) { case useA: A a; f(a); case useB: B b; f(b); } }
I need to generalize this to any number of enum values and any number of corresponding types.
Something like this (pseudocode):
typedef compile_time_map< mpl::pair<useA,A>, mpl::pair<useB,B>, ... > mapping;
template <typename F> void g(useType w, F f) { switch_apply( w, mapping, f ); }
Why not: std::map<useType, std::function<void(void)>> use_map = { { useA, [] { A a; f(a); } }, { useB, [] { B b, f(b); } } }; then: usemap.at(w)(); Or something similar ... Cheers, Leon

Leon Mlakar <leon <at> digiverse.si> writes:
Say I have this code. struct A {}; struct B {}; enum useType {useA, useB};
template <typename F> void g(useType w, F f) { switch (w) { case useA: A a; f(a); case useB: B b; f(b); } }
I need to generalize this to any number of enum values and any number
of
corresponding types.
Something like this (pseudocode):
typedef compile_time_map< mpl::pair<useA,A>, mpl::pair<useB,B>, ... > mapping;
template <typename F> void g(useType w, F f) { switch_apply( w, mapping, f ); }
Why not:
std::map<useType, std::function<void(void)>> use_map = { { useA, [] { A a; f(a); } }, { useB, [] { B b, f(b); } } };
Thanks for all the ideas. I found a solution [1] based on boost::fusion::for_each() which looks good enough for me (no variant, no heap allocations, no type-erasure). I believe it should be functionally equivalent to an if-else chain, and not as efficient as an actual switch, though. Regards [1] http://stackoverflow.com/questions/26846299/boost-fusion-run-time- switch

On Fri, Jul 31, 2015 at 9:54 AM, Leon Mlakar <leon@digiverse.si> wrote:
On 31.07.2015 15:10, dariomt wrote:
Michael <mwpowellhtx <at> gmail.com> writes:
On July 31, 2015 6:01:04 AM EDT, dariomt <at> gmail.com wrote:
Hi all,
Say I have a compile-time map of <value,type> pairs, and I need to access the correct element given a value at runtime and do something with
that
type. That something would be the same for any of the mapped types (e.g. calling an overloaded function that would then do the right thing depending on the type).
The value would typically be an enum.
Is there anything in the Boost libraries to help with this?
If I used C++11, would there be a simple solution to this?
Not really a boost question, perhaps.
I thought asking if Boost has tools to help with certain C++ problem was allowed in this list. Please correct me if I'm wrong.
First, I'm not sure why anyone wouldn't leverage at least C++11+.
Especially considering compiler
advancements in recent history. Optimization technology being what it
is and all. I'd rather use a well tested Boost component than a C++11 solution I have to implement, test and document.
That said, if it was me, I might have a look at a std::function (or
boost::function) "type factory" that knew
how to interface with an instance repository.
Could be a functor instance, as well, for that matter.
Regards
Cheers.
PS: I cannot use Boost.Variant
Why not?
Sorry, it is clear I didn't explain my problem well enough.
Say I have this code. struct A {}; struct B {}; enum useType {useA, useB};
template <typename F> void g(useType w, F f) { switch (w) { case useA: A a; f(a); case useB: B b; f(b); } }
I need to generalize this to any number of enum values and any number of corresponding types.
Something like this (pseudocode):
typedef compile_time_map< mpl::pair<useA,A>, mpl::pair<useB,B>, ... > mapping;
template <typename F> void g(useType w, F f) { switch_apply( w, mapping, f ); }
Why not:
std::map<useType, std::function<void(void)>> use_map = { { useA, [] { A a; f(a); } }, { useB, [] { B b, f(b); } } };
then:
usemap.at(w)();
Or something similar ...
Exactly along the lines what I described.
Cheers,
Leon
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users

On 07/31/2015 05:01 AM, dariomt@gmail.com wrote:
Hi all,
Say I have a compile-time map of <value,type> pairs, and I need to access the correct element given a value at runtime and do something with that type. That something would be the same for any of the mapped types (e.g. calling an overloaded function that would then do the right thing depending on the type).
The value would typically be an enum.
Is there anything in the Boost libraries to help with this?
If I used C++11, would there be a simple solution to this?
Regards
PS: I cannot use Boost.Variant
I've tried an alternative variant declared as: template < typename... Keys , typename... Vals
struct map < key_val_var<Keys, Vals>...
: key_val_var<Keys, Vals>... { private: typename std::aligned_union<our_size_value,Vals...>::type my_storage; std::size_t my_which; ... }' where key_val_var is: template <typename Key, typename Val> struct key_val_var { public: using key=Key; protected: template<typename... Args> static void construct ( void*storage , Args&&... args ) { new (storage) Val(std::forward<Args>(args)...); } static void destruct ( void*storage ) { auto p=static_cast<Val*>(storage); p->~Val(); } static Val* get_val_ptr ( void*storage ) { auto p=static_cast<Val*>(storage); return p; } When assigning a new value to this variant, the old value has to be destroyed based on the *runtime* value of my_which. This is done by indexing into a temp vector of the static destructs in the superclasses: void destroy_which() { typedef void(*destructor_t)(void*); destructor_t destructors[]= {key_val_var<Keys, Vals>::destruct...} ; destructors[my_which](storage()); } I'm guessing you could do something similar for the get_val_ptr's in the superclass. If you think it would help, I could post the code. -regards, Larry
participants (6)
-
dariomt
-
dariomt@gmail.com
-
Larry Evans
-
Leon Mlakar
-
Michael
-
Michael Powell