Boost logo

Boost :

Subject: Re: [boost] Is there interest in a library for string-convertible enums?
From: Felix Uhl (felix.uhl_at_[hidden])
Date: 2014-10-28 18:50:05


On 08/10/2014, Damien Buhl wrote:



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


Yes, interoperability with other boost libraries is a huge point to consider,

and I like the concepts of Boost.Fusion a lot.

I also thought about MPL, getting the names as compile time strings

could be really useful.


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


I don’t think it is possible to offer an ADAPT_STRUCT macro

without forcing the client to either rewrite every single value of the enumeration

or define the enum with another macro in the first place.

The former would could become problematic when clients change what values

the enum actually contains but forget to change that in the macro.

I would really want to enable the most natural syntax possible, but even a flexible

language like C++ has boundaries where you can’t bend it anymore.

So yes, I will offer both to the user.



Thanks for your feedback!


Felix Uhl








Von: Damien Buhl
Gesendet: ‎Dienstag‎, ‎28‎. ‎Oktober‎ ‎2014 ‎22‎:‎47
An: boost_at_[hidden]





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
>


_______________________________________________
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