<commit_before>/*
 * File: include/commonpp/core/Options.hpp
 * Part of commonpp.
 *
 * Distributed under the 2-clause BSD licence (See LICENCE.TXT file at the
 * project root).
 *
 * Copyright (c) 2016 <NAME>.  All rights reserved.
 *
 */
#pragma once

#include <iosfwd>
#include <type_traits>
#include <commonpp/core/config.hpp>
#include <commonpp/core/Utils.hpp>

#include <boost/preprocessor/stringize.hpp>
#include <boost/preprocessor/seq/elem.hpp>
#include <boost/preprocessor/seq/for_each.hpp>
#include <boost/preprocessor/variadic/to_seq.hpp>

namespace commonpp
{

template <typename Enum, Enum... initial_value>
struct Options
{
    using Underlying = typename std::underlying_type<Enum>::type;
    static_assert(std::is_unsigned<Underlying>::value, "Enum must be unsigned");

    constexpr Options() = default;

    template <typename... E>
    BOOST_CXX14_CONSTEXPR Options(E... v)
    {
        flag = set(initial_value..., v...);
    }

    Options& operator&=(Enum f)
    {
        flag |= enum_to_number(f);
        return *this;
    }

    Options& operator+=(Enum f)
    {
        flag |= enum_to_number(f);
        return *this;
    }

    Options& operator-=(Enum f)
    {
        flag = flag & ~enum_to_number(f);
        return *this;
    }

    bool operator&(Enum f) const
    {
        return (flag & enum_to_number(f)) != 0;
    }

    bool operator[](Enum f) const
    {
        return (flag & enum_to_number(f)) != 0;
    }

private:
    static constexpr Underlying set()
    {
        return 0;
    }

    static constexpr Underlying set(Enum value)
    {
        return enum_to_number(value);
    }

    template <typename Head, typename... Tail>
    static constexpr Underlying set(Head value, Tail... tail)
    {
        return set(value) | set(tail...);
    }

    Underlying flag = set(initial_value...);
};

#define COMMONPP_PRINT_OPTION_IF(R, Opts, Elem)                                \
    do                                                                         \
    {                                                                          \
        os << "Flag: " << BOOST_PP_STRINGIZE(Elem) << ": "                     \
           << ((Opts & Elem) ? "Enabled" : "Disabled") << ", ";                \
    } while (0);

#define COMMONPP_DECLARE_OPTIONS_OSTREAM_OP(Options)                           \
    std::ostream& operator<<(std::ostream& os, const Options& opt)

#define COMMONPP_GENERATE_OPTIONS_OSTREAM_OP(Options, Enum...)                 \
    COMMONPP_DECLARE_OPTIONS_OSTREAM_OP(Options)                               \
    {                                                                          \
        os << BOOST_PP_STRINGIZE(Options) << ": [";                            \
        BOOST_PP_SEQ_FOR_EACH(COMMONPP_PRINT_OPTION_IF, opt,                   \
                              BOOST_PP_VARIADIC_TO_SEQ(Enum))                  \
        os << "]";                                                             \
        return os;                                                             \
    }

} // namespace commonpp
<commit_msg>Fix a bug with clang and boost PP when boost <= 1.55<commit_after>/*
 * File: include/commonpp/core/Options.hpp
 * Part of commonpp.
 *
 * Distributed under the 2-clause BSD licence (See LICENCE.TXT file at the
 * project root).
 *
 * Copyright (c) 2016 <NAME>.  All rights reserved.
 *
 */
#pragma once

#include <iosfwd>
#include <type_traits>
#include <commonpp/core/config.hpp>
#include <commonpp/core/Utils.hpp>

#if BOOST_CLANG == 1 && BOOST_MAJOR == 1 && BOOST_MAJOR <= 55
# if defined(BOOST_PP_VARIADICS)
#  if !BOOST_PP_VARIADICS
#   warning BOOST_PP_VARIADICS cannot be defined as 0, redefining it to 1a
#   undef BOOST_PP_VARIADICS
#   define BOOST_PP_VARIADICS 1
#  endif
# else
#  define BOOST_PP_VARIADICS 1
# endif
#endif


#include <boost/preprocessor/stringize.hpp>
#include <boost/preprocessor/seq/elem.hpp>
#include <boost/preprocessor/seq/for_each.hpp>
#include <boost/preprocessor/variadic/to_seq.hpp>

namespace commonpp
{

template <typename Enum, Enum... initial_value>
struct Options
{
    using Underlying = typename std::underlying_type<Enum>::type;
    static_assert(std::is_unsigned<Underlying>::value, "Enum must be unsigned");

    constexpr Options() = default;

    template <typename... E>
    BOOST_CXX14_CONSTEXPR Options(E... v)
    {
        flag = set(initial_value..., v...);
    }

    Options& operator&=(Enum f)
    {
        flag |= enum_to_number(f);
        return *this;
    }

    Options& operator+=(Enum f)
    {
        flag |= enum_to_number(f);
        return *this;
    }

    Options& operator-=(Enum f)
    {
        flag = flag & ~enum_to_number(f);
        return *this;
    }

    bool operator&(Enum f) const
    {
        return (flag & enum_to_number(f)) != 0;
    }

    bool operator[](Enum f) const
    {
        return (flag & enum_to_number(f)) != 0;
    }

private:
    static constexpr Underlying set()
    {
        return 0;
    }

    static constexpr Underlying set(Enum value)
    {
        return enum_to_number(value);
    }

    template <typename Head, typename... Tail>
    static constexpr Underlying set(Head value, Tail... tail)
    {
        return set(value) | set(tail...);
    }

    Underlying flag = set(initial_value...);
};

#define COMMONPP_PRINT_OPTION_IF(R, Opts, Elem)                                \
    do                                                                         \
    {                                                                          \
        os << "Flag: " << BOOST_PP_STRINGIZE(Elem) << ": "                     \
           << ((Opts & Elem) ? "Enabled" : "Disabled") << ", ";                \
    } while (0);

#define COMMONPP_DECLARE_OPTIONS_OSTREAM_OP(Options)                           \
    std::ostream& operator<<(std::ostream& os, const Options& opt)

#define COMMONPP_GENERATE_OPTIONS_OSTREAM_OP(Options, Enum...)                 \
    COMMONPP_DECLARE_OPTIONS_OSTREAM_OP(Options)                               \
    {                                                                          \
        os << BOOST_PP_STRINGIZE(Options) << ": [";                            \
        BOOST_PP_SEQ_FOR_EACH(COMMONPP_PRINT_OPTION_IF, opt,                   \
                              BOOST_PP_VARIADIC_TO_SEQ(Enum))                  \
        os << "]";                                                             \
        return os;                                                             \
    }

} // namespace commonpp

{'fraction_non_alphanumeric': 0.11320754716981132, 'fraction_numerical': 0.00502130249543518, 'mean_word_length': 1.563572542901716, 'pattern_counts': {'":': 4, '<': 69, '<?xml version=': 0, '>': 31, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 26, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1764464', 'n_tokens_mistral': 1985, 'n_tokens_neox': 1877, 'n_words': 405}