, .
. , , . .
typedef unsigned char uint8_t;
typedef unsigned size_t;
template <typename T, size_t N> struct array {
T elem[N];
constexpr size_t size() { return N; }
constexpr T operator[](size_t i) { return elem[i]; }
};
template <typename T, T... Values> struct integer_sequence
{
typedef T value_type;
};
typedef bool(*predicate)(int);
template <bool Check, typename IfTrue, typename IfFalse> struct s_if;
template <typename IfTrue, typename IfFalse> struct s_if<true , IfTrue, IfFalse> {using type = IfTrue ;};
template <typename IfTrue, typename IfFalse> struct s_if<false, IfTrue, IfFalse> {using type = IfFalse;};
template <bool Check, typename IfTrue, typename IfFalse>
using f_if = typename s_if<Check, IfTrue, IfFalse>::type;
template <typename T, T Car, typename Cdr> struct s_integer_sequence_cons;
template <typename T, T Car, T... Cdr> struct s_integer_sequence_cons<T, Car, integer_sequence<T, Cdr...>>
{ using type = integer_sequence<T, Car, Cdr...>; };
template <typename T, T Car, typename Cdr>
using f_cons = typename s_integer_sequence_cons<T, Car, Cdr>::type;
template <typename T, typename S1, typename S2> struct s_integer_sequence_append;
template <typename T, T... S1, T... S2> struct s_integer_sequence_append<T, integer_sequence<T, S1...>, integer_sequence<T, S2...>>
{ using type = integer_sequence<T, S1..., S2...>; };
template <typename S1, typename S2>
using f_append = typename s_integer_sequence_append<S1::value_type, S1, S2>::type;
template <typename Sequence, predicate pred> struct s_filter;
template <typename T, predicate pred> struct s_filter<integer_sequence<T>, pred>
{
using type = integer_sequence<T>;
};
template <typename T, T Car, T...Cdr, predicate pred> struct s_filter<integer_sequence<T, Car, Cdr...>, pred>
{
using tail = typename s_filter<integer_sequence<T, Cdr...>, pred>::type;
using type = f_if<pred(Car),
f_cons<T, Car, tail>,
tail>;
};
template <typename Sequence, predicate pred>
using f_filter = typename s_filter<Sequence, pred>::type;
template <int I , typename T> constexpr T find_index (T elem) { return -1; }
template <int I=0, typename T, typename... List> constexpr T find_index (T elem, T val, List... rest)
{ return elem == val ? I : find_index<I+1>(elem, rest...); }
template <typename Target, typename Origin> struct s_index_list;
template <typename T, typename Origin> struct s_index_list<integer_sequence<T>, Origin>
{
using type = integer_sequence<T>;
};
template <typename T, T Car, T... Cdr, T...Origin> struct s_index_list<integer_sequence<T, Car, Cdr...>, integer_sequence<T, Origin...>>
{
using tail = typename s_index_list<integer_sequence<T, Cdr...>, integer_sequence<T, Origin...>>::type;
using type = f_cons<T, find_index(Car, Origin...), tail>;
};
template <typename Target, typename Origin>
using f_index = typename s_index_list<Target, Origin>::type;
template <typename T, T... x> constexpr array<T, sizeof...(x)> integer_sequence_to_array(integer_sequence<T, x...>)
{ return array<T, sizeof...(x)> { x... }; }
#define input_list 2,10,4,7,9,3
typedef integer_sequence<uint8_t, input_list> input_sequence;
constexpr bool test_group_1(int n) { return (n >> 3) == 0; }
constexpr bool test_group_2(int n) { return (n >> 3) == 1; }
typedef f_filter<input_sequence, test_group_1> sequence_1;
typedef f_filter<input_sequence, test_group_2> sequence_2;
typedef f_append<sequence_1, sequence_2> output_sequence;
typedef f_index<output_sequence, input_sequence> output_indexes;
constexpr auto const_values = integer_sequence_to_array(output_sequence{});
constexpr auto const_indexes = integer_sequence_to_array(output_indexes {});
- . 20 , (Python, PHP, Perl, awk, ...),
#define my_list 2,10,4,7,9,3
const int filtered_list [] = {2,4,7,3};
const size_t filtered_index[] = {0,-1,1,2,-1,3};
++.
, ++, - Arduino. , , . Arduino make , , " Arduino" , gnu ++ 11, stdlib.
, ++ , .
, , , . , , , .
LISP, , cons, append if, -, , . . , , .
, , , stdlib . , .
I finally came up with something that actually does the job of just under 100 lines of very confusing code.
I'm not looking for efficiency here, my lists are unlikely to contain more than a dozen values, but I would be happy to observe and learn to achieve the same result with less source code. Any members?