/
none.hpp
72 lines (64 loc) · 2.54 KB
/
none.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
/*==================================================================================================
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/all.hpp>
#include <brigand/algorithms/detail/non_null.hpp>
#include <brigand/functions/lambda/apply.hpp>
#include <brigand/types/bool.hpp>
namespace brigand
{
#if defined(BRIGAND_COMP_MSVC_2013) || defined(BRIGAND_COMP_CUDA) || defined(BRIGAND_COMP_INTEL)
namespace detail
{
template <typename Sequence, typename Pred>
struct none_impl
{
template <typename T>
struct nope
{
using that = brigand::apply<Pred, T>;
using type = bool_<!that::value>;
};
using type = all<Sequence, nope<_1>>;
};
}
#else
namespace detail
{
template <typename Sequence, typename Predicate>
struct none_impl : bool_<true>
{
};
template <template <class...> class Sequence, typename Predicate, typename T, typename... Ts>
struct none_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 none_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 none_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 no type ?
template <typename Sequence, typename Predicate = detail::non_null>
using none = typename detail::none_impl<Sequence, Predicate>::type;
}