vSMC
vSMC: Scalable Monte Carlo
traits.hpp
Go to the documentation of this file.
1 //============================================================================
2 // vSMC/include/vsmc/internal/traits.hpp
3 //----------------------------------------------------------------------------
4 // vSMC: Scalable Monte Carlo
5 //----------------------------------------------------------------------------
6 // Copyright (c) 2013-2016, Yan Zhou
7 // All rights reserved.
8 //
9 // Redistribution and use in source and binary forms, with or without
10 // modification, are permitted provided that the following conditions are met:
11 //
12 // Redistributions of source code must retain the above copyright notice,
13 // this list of conditions and the following disclaimer.
14 //
15 // Redistributions in binary form must reproduce the above copyright notice,
16 // this list of conditions and the following disclaimer in the documentation
17 // and/or other materials provided with the distribution.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS
20 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 // POSSIBILITY OF SUCH DAMAGE.
30 //============================================================================
31 
32 #ifndef VSMC_INTERNAL_TRAITS_HPP
33 #define VSMC_INTERNAL_TRAITS_HPP
34 
35 #include <vsmc/internal/config.h>
38 #include <type_traits>
39 
40 #define VSMC_DEFINE_TYPE_DISPATCH_TRAIT(Outer, Inner, Default) \
41  template <typename T> \
42  class Outer##Trait; \
43  \
44  namespace internal \
45  { \
46  \
47  template <typename T> \
48  class Has##Outer##Impl \
49  { \
50  class char2 \
51  { \
52  char c1; \
53  char c2; \
54  }; \
55  \
56  template <typename U> \
57  static char test(typename U::Inner *); \
58  \
59  template <typename U> \
60  static char2 test(...); \
61  \
62  public: \
63  static constexpr bool value = \
64  sizeof(test<T>(nullptr)) == sizeof(char); \
65  }; \
66  \
67  template <typename T> \
68  class Has##Outer \
69  : public std::integral_constant<bool, Has##Outer##Impl<T>::value> \
70  { \
71  }; \
72  \
73  template <typename T, bool> \
74  class Outer##Dispatch; \
75  \
76  template <typename T> \
77  class Outer##Dispatch<T, false> \
78  { \
79  public: \
80  using type = Default; \
81  }; \
82  \
83  template <typename T> \
84  class Outer##Dispatch<T, true> \
85  { \
86  public: \
87  using type = typename T::Inner; \
88  }; \
89  \
90  } /* namespace interanl */ \
91  \
92  template <typename T> \
93  class Outer##Trait \
94  { \
95  public: \
96  static constexpr bool value = internal::Has##Outer<T>::value; \
97  using type = typename internal::Outer##Dispatch<T, value>::type; \
98  }; \
99  \
100  template <typename T> \
101  using Outer = typename Outer##Trait<T>::type;
102 
103 #define VSMC_DEFINE_TYPE_TEMPLATE_DISPATCH_TRAIT(Outer, Inner, Default) \
104  template <typename T> \
105  class Outer##Trait; \
106  \
107  namespace internal \
108  { \
109  \
110  template <typename T> \
111  class Has##Outer##Impl \
112  { \
113  class char2 \
114  { \
115  char c1; \
116  char c2; \
117  }; \
118  \
119  template <typename U> \
120  static char test(typename U::template Inner<T> *); \
121  \
122  template <typename U> \
123  static char2 test(...); \
124  \
125  public: \
126  static constexpr bool value = \
127  sizeof(test<T>(nullptr)) == sizeof(char); \
128  }; \
129  \
130  template <typename T> \
131  class Has##Outer \
132  : public std::integral_constant<bool, Has##Outer##Impl<T>::value> \
133  { \
134  }; \
135  \
136  template <typename T, bool> \
137  class Outer##Dispatch; \
138  \
139  template <typename T> \
140  class Outer##Dispatch<T, false> \
141  { \
142  public: \
143  using type = Default<T>; \
144  }; \
145  \
146  template <typename T> \
147  class Outer##Dispatch<T, true> \
148  { \
149  public: \
150  using type = typename T::template Inner<T>; \
151  }; \
152  } \
153  \
154  template <typename T> \
155  class Outer##Trait \
156  { \
157  public: \
158  static constexpr bool value = internal::Has##Outer<T>::value; \
159  using type = typename internal::Outer##Dispatch<T, value>::type; \
160  }; \
161  \
162  template <typename T> \
163  using Outer = typename Outer##Trait<T>::type;
164 
165 #define VSMC_DEFINE_METHOD_CHECKER(name, RT, Args) \
166  template <typename U> \
167  class has_##name##_impl_ \
168  { \
169  class char2 \
170  { \
171  char c1; \
172  char c2; \
173  }; \
174  \
175  template <typename V, RT(V::*) Args> \
176  class sfinae_; \
177  \
178  template <typename V, RT(V::*) Args const> \
179  class sfinae_const_; \
180  \
181  template <typename V, RT(*) Args> \
182  class sfinae_static_; \
183  \
184  template <typename V> \
185  static char test(sfinae_<V, &V::name> *); \
186  \
187  template <typename V> \
188  static char test(sfinae_const_<V, &V::name> *); \
189  \
190  template <typename V> \
191  static char test(sfinae_static_<V, &V::name> *); \
192  \
193  template <typename V> \
194  static char2 test(...); \
195  \
196  public: \
197  static constexpr bool value = \
198  sizeof(test<U>(nullptr)) == sizeof(char); \
199  }; \
200  \
201  template <typename U> \
202  class has_##name##_ \
203  : public std::integral_constant<bool, has_##name##_impl_<U>::value> \
204  { \
205  }; // class has_##name##_
206 
207 namespace vsmc
208 {
209 
213 
214 namespace internal
215 {
216 
217 template <typename T, typename T1, typename... Types>
218 class is_one_of : public std::integral_constant<bool,
219  is_one_of<T, T1>::value || is_one_of<T, Types...>::value>
220 {
221 }; // class is_one_of
222 
223 template <typename T, typename T1>
224 class is_one_of<T, T1>
225  : public std::integral_constant<bool, std::is_same<T, T1>::value>
226 {
227 }; // class is_one_of
228 
229 template <typename T, typename T1, typename... Types>
231  : public std::integral_constant<bool,
232  is_seed_seq<T, T1>::value && is_seed_seq<T, Types...>::value>
233 {
234 };
235 
236 template <typename T, typename T1>
237 class is_seed_seq<T, T1>
238  : public std::integral_constant<bool, !std::is_convertible<T, T1>::value &&
239  !std::is_same<typename std::remove_cv<T>::type, T1>::value>
240 {
241 }; // class is_seed_seq
242 
243 } // namespace vsmc::internal
244 
245 } // namespace vsmc
246 
247 #endif // VSMC_INTERNAL_TRAITS_HPP
#define VSMC_DEFINE_TYPE_DISPATCH_TRAIT(Outer, Inner, Default)
Definition: traits.hpp:40
Definition: monitor.hpp:49
typename SizeTypeTrait< T >::type SizeType
Definition: traits.hpp:212