Лучший способ определить набор значений constexpr для немутирующих алгоритмов - PullRequest
0 голосов
/ 24 июня 2018

Я хотел бы использовать немутантные алгоритмы из <algorithm> и алгоритмы увеличения диапазона для набора значений, известных во время компиляции. Я хочу знать, какой подход будет наиболее эффективным (с точки зрения производительности и памяти), исключая подход с использованием переключателей.

Давайте рассмотрим enum (класс или нет) с некоторыми значениями.

enum Enum
{
   One,
   Two,
   Three
};

Рассмотрим тривиальную функцию bool isOneOrTwo(Enum e). Используя подход <algorithm>, я знаю, что это можно записать двумя способами: 1. std::initializer_list<T>

bool isOneOrTwo(Enum e)
{
    constexpr std::initializer<Enum> oneAndTwo{One, Two};
    return std::any_of(std::begin(oneAndTwo),
                       std::end(oneAndTwo),
                       [e](auto i){return e == i;});
}

2. std::array<T,N>

У нас есть make_pair и make_tuple, но, к сожалению, у нас нет функции make_array<T>(T&&..), поэтому я написал одну:

template<typename... T>
constexpr auto make_array(T&&... args)
{
    return std::array<typename std::common_type<T...>::type, sizeof...(T)>{{std::forward<T>(args)...}};
}

Тогда функцию можно выполнить следующим образом:

bool isOneOrTwo(Enum e)
{
    constexpr auto oneAndTwo = make_array(One, Two);
    return std::any_of(std::begin(oneAndTwo),
                       std::end(oneAndTwo),
                       [e](auto i){return e == i;});
}

Какой из них лучше (std::initializer_list<T> или std::array<T,N>) или есть другой способ сделать это быстрее / дешевле?

И окажет ли это влияние, если я поменяю std::any_of(begin_it, end_it, lambda) на boost::algorithm::any_of_equal(make_iterator_range(begin_it, end_it), value)?

...