<commit_before>//----------------------------------------------------------------------------
/// \file   enum.hpp
/// \author <NAME>
//----------------------------------------------------------------------------
/// \brief This file defines enum stringification declaration macro.
//----------------------------------------------------------------------------
// Copyright (c) 2014 <NAME> <<EMAIL>>
// Created: 2014-09-31
//----------------------------------------------------------------------------
/*
***** BEGIN LICENSE BLOCK *****

This file is part of the utxx open-source project.

Copyright (C) 2014 <NAME> <<EMAIL>>

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

***** END LICENSE BLOCK *****
*/
#pragma once

#include <boost/preprocessor/variadic/to_seq.hpp>
#include <boost/preprocessor/variadic/size.hpp>
#include <boost/preprocessor/seq/enum.hpp>
#include <boost/preprocessor/seq/for_each.hpp>
#include <boost/preprocessor/seq/transform.hpp>
#include <boost/preprocessor/seq/size.hpp>
#include <boost/preprocessor/stringize.hpp>
#include <boost/preprocessor/facilities/empty.hpp>
#include <utxx/string.hpp>
#include <cassert>

// Enum declaration:
//  #include <utxx/enum.hpp>
//
//  UTXX_DEFINE_ENUM(MyEnumT,
//                      Apple,
//                      Pear,
//                      Grape
//                  );
//
// Sample usage:
//  MyEnumT val = MyEnumT::from_string("Pear");
//  std::cout << "Value: " << to_string(val) << std::endl;
//  std::cout << "Value: " << val            << std::endl;
//
#define UTXX_DEFINE_ENUM(ENUM, ...)                                         \
    struct ENUM {                                                           \
        enum etype {                                                        \
            UNDEFINED,                                                      \
            __VA_ARGS__,                                                    \
            _END_                                                           \
        };                                                                  \
                                                                            \
    private:                                                                \
        static const size_t s_size = 1+BOOST_PP_VARIADIC_SIZE(__VA_ARGS__); \
        static const std::string* names() {                                 \
            static const std::string s_names[] = {                          \
                "UNDEFINED",                                                \
                BOOST_PP_SEQ_ENUM(                                          \
                    BOOST_PP_SEQ_TRANSFORM(                                 \
                        UTXX_INTERNAL_ENUM_STRINGIFY, ,                     \
                        BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__)               \
                ))                                                          \
            };                                                              \
            return s_names;                                                 \
        };                                                                  \
                                                                            \
        static const std::string& name(size_t n) {                          \
            assert(n < s_size);                                             \
            return names()[n];                                              \
        };                                                                  \
                                                                            \
        etype  m_val;                                                       \
                                                                            \
    public:                                                                 \
        explicit  ENUM(size_t v) : m_val(etype(v)) { assert(v < s_size); }  \
        constexpr ENUM()         : m_val(UNDEFINED) {}                      \
        constexpr ENUM(etype v)  : m_val(v) {}                              \
                                                                            \
        constexpr operator etype()     const { return m_val; }              \
        constexpr bool     empty()     const { return m_val == UNDEFINED; } \
                                                                            \
        const std::string& to_string() const { return name(size_t(m_val));} \
        static const std::string&                                           \
                           to_string(etype a){ return ENUM(a).to_string();} \
        const char*        c_str()     const { return to_string().c_str(); }\<commit_msg>Removed extraneous semicolons in enum.hpp which trigger compiler warnings after macro expansion<commit_after>//----------------------------------------------------------------------------
/// \file   enum.hpp
/// \author <NAME>
//----------------------------------------------------------------------------
/// \brief This file defines enum stringification declaration macro.
//----------------------------------------------------------------------------
// Copyright (c) 2014 <NAME> <<EMAIL>>
// Created: 2014-09-31
//----------------------------------------------------------------------------
/*
***** BEGIN LICENSE BLOCK *****

This file is part of the utxx open-source project.

Copyright (C) 2014 <NAME> <<EMAIL>>

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

***** END LICENSE BLOCK *****
*/
#pragma once

#include <boost/preprocessor/variadic/to_seq.hpp>
#include <boost/preprocessor/variadic/size.hpp>
#include <boost/preprocessor/seq/enum.hpp>
#include <boost/preprocessor/seq/for_each.hpp>
#include <boost/preprocessor/seq/transform.hpp>
#include <boost/preprocessor/seq/size.hpp>
#include <boost/preprocessor/stringize.hpp>
#include <boost/preprocessor/facilities/empty.hpp>
#include <utxx/string.hpp>
#include <cassert>

// Enum declaration:
//  #include <utxx/enum.hpp>
//
//  UTXX_DEFINE_ENUM(MyEnumT,
//                      Apple,
//                      Pear,
//                      Grape
//                  );
//
// Sample usage:
//  MyEnumT val = MyEnumT::from_string("Pear");
//  std::cout << "Value: " << to_string(val) << std::endl;
//  std::cout << "Value: " << val            << std::endl;
//
#define UTXX_DEFINE_ENUM(ENUM, ...)                                         \
    struct ENUM {                                                           \
        enum etype {                                                        \
            UNDEFINED,                                                      \
            __VA_ARGS__,                                                    \
            _END_                                                           \
        };                                                                  \
                                                                            \
    private:                                                                \
        static const size_t s_size = 1+BOOST_PP_VARIADIC_SIZE(__VA_ARGS__); \
        static const std::string* names() {                                 \
            static const std::string s_names[] = {                          \
                "UNDEFINED",                                                \
                BOOST_PP_SEQ_ENUM(                                          \
                    BOOST_PP_SEQ_TRANSFORM(                                 \
                        UTXX_INTERNAL_ENUM_STRINGIFY, ,                     \
                        BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__)               \
                ))                                                          \
            };                                                              \
            return s_names;                                                 \
        }                                                                   \
                                                                            \
        static const std::string& name(size_t n) {                          \
            assert(n < s_size);                                             \
            return names()[n];                                              \
        }                                                                   \
                                                                            \
        etype  m_val;                                                       \
                                                                            \
    public:                                                                 \
        explicit  ENUM(size_t v) : m_val(etype(v)) { assert(v < s_size); }  \
        constexpr ENUM()         : m_val(UNDEFINED) {}                      \
        constexpr ENUM(etype v)  : m_val(v) {}                              \
                                                                            \
        constexpr operator etype()     const { return m_val; }              \
        constexpr bool     empty()     const { return m_val == UNDEFINED; } \
                                                                            \
        const std::string& to_string() const { return name(size_t(m_val));} \
        static const std::string&                                           \
                           to_string(etype a){ return ENUM(a).to_string();} \
        const char*        c_str()     const { return to_string().c_str(); }\
{'fraction_non_alphanumeric': 0.13358497514269932, 'fraction_numerical': 0.006076229055422574, 'mean_word_length': 0.7411444141689373, 'pattern_counts': {'":': 0, '<': 67, '<?xml version=': 0, '>': 39, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 124, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5409482', 'n_tokens_mistral': 2202, 'n_tokens_neox': 2079, 'n_words': 583}