/
all.hpp
89 lines (79 loc) · 2.99 KB
/
all.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
/*==================================================================================================
Copyright (c) 2015 Edouard Alligand and Joel Falcou
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
=================================================================================================**/
#pragma once
#include <brigand/algorithms/detail/non_null.hpp>
#include <brigand/config.hpp>
#include <brigand/functions/lambda/apply.hpp>
#include <initializer_list>
#include <type_traits>
namespace brigand
{
#if defined(BRIGAND_COMP_MSVC_2013) || defined(BRIGAND_COMP_CUDA) || defined(BRIGAND_COMP_INTEL)
namespace detail
{
template <class P, class T>
struct all_helper : ::brigand::apply<P, T>
{
};
template <bool...>
struct bools_
{
};
template <typename Sequence, typename Predicate, typename... Ts>
struct all_impl;
template <template <class...> class Sequence, typename Predicate, typename... Ts>
struct all_impl<Sequence<Ts...>, Predicate>
: std::is_same<bools_<true, all_helper<Predicate, Ts>::value...>,
bools_<all_helper<Predicate, Ts>::value..., true>>
{
};
}
#else
namespace detail
{
struct all_same
{
const bool value = false;
constexpr all_same(...) {}
template <typename T>
constexpr all_same(std::initializer_list<T *>) : value{true}
{
}
};
template <typename Sequence, typename Predicate>
struct all_impl : bool_<true>
{
};
template <template <class...> class Sequence, typename Predicate, typename T, typename... Ts>
struct all_impl<Sequence<T, Ts...>, Predicate>
{
static constexpr all_same tester{
static_cast< ::brigand::apply<Predicate, T> *>(nullptr),
static_cast< ::brigand::apply<Predicate, Ts> *>(nullptr)...};
using type = bool_<(::brigand::apply<Predicate, T>::value != 0 && tester.value)>;
};
template <template <class...> class Sequence, template <typename...> class F, typename T,
typename... Ts>
struct all_impl<Sequence<T, Ts...>, bind<F, _1>>
{
static constexpr all_same tester{static_cast<F<T> *>(nullptr),
static_cast<F<Ts> *>(nullptr)...};
using type = bool_<(F<T>::value != 0 && tester.value)>;
};
template <template <class...> class Sequence, template <typename...> class F, typename T,
typename... Ts>
struct all_impl<Sequence<T, Ts...>, F<_1>>
{
static constexpr all_same tester{static_cast<typename F<T>::type *>(nullptr),
static_cast<typename F<Ts>::type *>(nullptr)...};
using type = bool_<(F<T>::type::value != 0 && tester.value)>;
};
}
#endif
// Is a predicate true for every type ?
template <typename Sequence, typename Predicate = detail::non_null>
using all = typename detail::all_impl<Sequence, Predicate>::type;
}