I'm not sure if Boost is available in your scenario, so here is a solution where the enum
has to be defined in a pre-processor sequence. That sequence is then used to build the enum and a corresponding mpl::vector
and we compute if the elements of the vector
are unique in an odd-fashion. We might want to define a proper is_unique
algorithm first, but this should do.
#include <boost/mpl/vector.hpp>
#include <boost/mpl/int.hpp>
#include <boost/mpl/sort.hpp>
#include <boost/mpl/unique.hpp>
#include <boost/mpl/size.hpp>
#include <boost/preprocessor/tuple/elem.hpp>
#include <boost/preprocessor/seq/enum.hpp>
#include <boost/preprocessor/seq/transform.hpp>
#define MYENUM ((FOO, 0))((BAR, 1))((BAZ, 2))
#define GET_NAME(_, __, elem) BOOST_PP_TUPLE_ELEM(2, 0, elem) = BOOST_PP_TUPLE_ELEM(2, 1, elem)
#define GET_VALUE(_, __, elem) boost::mpl::int_<BOOST_PP_TUPLE_ELEM(2, 1, elem)>
enum E {
BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_TRANSFORM(GET_NAME, _, MYENUM))
};
typedef boost::mpl::sort<
boost::mpl::vector<
BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_TRANSFORM(GET_VALUE, _, MYENUM))
>
>::type evalues;
typedef boost::mpl::unique< evalues, boost::is_same<boost::mpl::_1, boost::mpl::_2> >::type uniqued;
static_assert(boost::mpl::size<uniqued>::value == boost::mpl::size<evalues>::value, "enum values not unique");
int main()
{
return 0;
}
If you change the enum definition to:
#define MYENUM ((FOO, 0))((BAR, 1))((BAZ, 2))((BAZZ, 2))
you will get an error stating the static_assert failed "enum values not unique"
.