Boost logo

Boost :

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://lists.boost.org/mailman/listinfo.cgi/boost
> 

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk