$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
Subject: Re: [boost] Is there interest in a library for string-convertible enums?
From: Damien Buhl (damien.buhl_at_[hidden])
Date: 2014-10-28 17:47:35
Hi Felix,
Personally I'm interested, because so far I've been always using a silly
macro for this, which doesn't make much :
> #ifndef SWISSARMYKNIFE_ENUMS_ADAPT_ENUM_HPP
> #define SWISSARMYKNIFE_ENUMS_ADAPT_ENUM_HPP
> 
> #include <string>
> #include <ostream>
> #include <boost/preprocessor/cat.hpp>
> #include <boost/preprocessor/stringize.hpp>
> #include <boost/preprocessor/seq/for_each.hpp>
> 
> 
> #define SWISSARMYKNIFE_ADAPT_ENUM_EACH_ENUMERATION_ENTRY_C(                     \
>     R, unused, ENUMERATION_ENTRY)                                               \
>     case ENUMERATION_ENTRY:                                                     \
>       return BOOST_PP_STRINGIZE(ENUMERATION_ENTRY);                             \
>     break;                                                                      
> 
> #define SWISSARMYKNIFE_ADAPT_ENUM(ENUM_TYPE, ENUMERATION_SEQ)                   \
>     inline std::string to_string(const ENUM_TYPE& enum_value) {                 \
>       switch (enum_value) {                                                     \
>       BOOST_PP_SEQ_FOR_EACH(                                                    \
>           SWISSARMYKNIFE_ADAPT_ENUM_EACH_ENUMERATION_ENTRY_C,                   \
>           unused, ENUMERATION_SEQ)                                              \
>         default:                                                                \
>           return BOOST_PP_STRINGIZE(ENUM_TYPE);                                 \
>       }                                                                         \
>     }                                                                           \
>                                                                                 \
>     inline std::ostream& operator<<(std::ostream& os, const ENUM_TYPE& value) { \
>       os << to_string(value);                                                   \
>       return os;                                                                \
>     }
> 
> #endif
What I would like to is to have a complete adapted enum for
Boost.Fusion, this was implemented at some point in some old version of
Boost.Fusion but I cannot find it anymore.
Because if this had the extension struct_member_name or some other
better named extension, then I could print out all the possible states
with some generic code like I print struct member name with
"boost::fusion::for_each_member(enumValue, *this);"
> #ifndef BOOST_FUSION_FOR_EACH_MEMBER_HPP
> #define BOOST_FUSION_FOR_EACH_MEMBER_HPP
> 
> #include <functional>
> 
> #include <boost/fusion/include/adapt_struct.hpp> 
> 
> #include <boost/fusion/sequence/intrinsic/begin.hpp>
> #include <boost/fusion/sequence/intrinsic/end.hpp>
> #include <boost/fusion/sequence/intrinsic/front.hpp>
> #include <boost/fusion/iterator/equal_to.hpp>
> #include <boost/fusion/iterator/next.hpp>
> #include <boost/fusion/iterator/deref.hpp>
> #include <boost/fusion/iterator/distance.hpp>
> #include <boost/fusion/support/category_of.hpp>
> #include <boost/mpl/bool.hpp>
> 
> namespace boost { namespace fusion {
> 
> namespace detail {
> 
>   template <typename First, typename Last, typename F>
>   inline void
>   for_each_member_linear(First const& first, 
>       Last const& last, 
>       F const& f,
>       boost::mpl::true_) {}
> 
>   template <typename First, typename Last, typename F>
>   inline void
>   for_each_member_linear(First const& first, 
>       Last const& last,
>       F const& f,
>       boost::mpl::false_) {
> 
>       f(
> 				extension::struct_member_name<
> 					typename First::seq_type, First::index::value
> 				>::call(), 
> 				*first
> 			);
> 
>       for_each_member_linear(
>           next(first), 
>           last,
>           f,
>           result_of::equal_to< typename result_of::next<First>::type, Last>()
>       );
>   }
> 
>   template <typename Sequence, typename F>
>   inline void
>   for_each_member(Sequence& seq, F const& f) {
> 
>     detail::for_each_member_linear(
>       fusion::begin(seq), 
>       fusion::end(seq), 
>       f, 
>       result_of::equal_to<
>         typename result_of::begin<Sequence>::type, 
>         typename result_of::end<Sequence>::type>()
>     );
>   }
> 
> }
> 
>   template <typename Sequence, typename F>
>   inline void
>   for_each_member(Sequence& seq, F f) {
>     detail::for_each_member(seq, f);
>   }
>  
> }}
> 
> #endif
And before all it's important I believe that it doesn't ask the user to
write the enums with macros, but that an additional call later to
something like BOOST_ADAPT_ENUM adds the boilerplate code.
It's naturally possible to offer both choice to the user like
BOOST_FUSION_ADAPT_STRUCT / BOOST_FUSION_DEFINE_STRUCT.
Cheers,
-- Damien Buhl On 10/28/2014 12:09 PM, Felix Uhl wrote: > So far, the only way to convert an enumeration value to a string is a lot of boilerplate code consisting of switch case statements for every single possible value of the enum. > > > IâÂÂve written a small header-only library that uses Boost.Preprocessor and templates to ease the definition of named enumerations that are convertible to and from strings. Those can also be used with the std::cin and std::cout streams naturally, while maintaining all syntactic and semantic properties, regarding initialisation, assignment, type safety and conversion to underlying types. > > > Currently, I am documenting the first version of the library to make it available on the Boost Library Incubator website, but I wanted to get some initial feedback from the developers mailing list, too. I would be glad to extend the library to a general extension of enumeration behaviour, like changing the generation of underlying values from a continuous increment to a continuous shift left by one, effectively making the underlying values binary flags. > > > What features would you want from such a library? Is there even a chance that such a library would get included in boost (given that it satisfied the quality requirements), or is there too little interest in this functionality? > > _______________________________________________ > Unsubscribe & other changes: http://listarchives.boost.org/mailman/listinfo.cgi/boost >