MADNESS 0.10.1
type_traits.h
Go to the documentation of this file.
1/*
2 This file is part of MADNESS.
3
4 Copyright (C) 2007,2010 Oak Ridge National Laboratory
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
20 For more information please contact:
21
22 Robert J. Harrison
23 Oak Ridge National Laboratory
24 One Bethel Valley Road
25 P.O. Box 2008, MS-6367
26
27 email: harrisonrj@ornl.gov
28 tel: 865-241-3937
29 fax: 865-572-0680
30*/
31
32#ifndef MADNESS_WORLD_TYPE_TRAITS_H__INCLUDED
33#define MADNESS_WORLD_TYPE_TRAITS_H__INCLUDED
34
35/// \file typestuff.h
36/// \brief type traits and templates
37
38/*
39 * N.B. this must be pure c++, usable without any context other than
40 * the current compiler + library + C++ standard.
41 * DO NOT include non-standard headers here!
42 */
43
44#include <cstddef>
45#include <cstdint>
46#include <type_traits>
47#include <iosfwd>
48#include <madness/world/meta.h>
49#include <vector>
50
51namespace madness {
52
53 namespace operators {
54 class __x {};
55 std::ostream& operator<<(std::ostream&, const __x&);
56 std::ostream& operator>>(std::ostream&, __x&);
57 } // namespace operators
58
59 // fwd decls
60 namespace archive {
61 template <typename Archive, typename T, typename Enabler = void>
62 struct ArchiveSerializeImpl;
63
64 template <class Archive, class T, typename Enabler = void>
65 struct ArchiveLoadImpl;
66
67 template <class Archive, class T, typename Enabler = void>
68 struct ArchiveStoreImpl;
69
70 template <class Archive, class T, typename Enabler = void>
71 struct ArchiveImpl;
72 }
73
74 template <typename> class Future;
75
76 /// test if a type is a future.
77
78 /// \tparam T The type to test.
79 template <typename T>
80 struct is_future : public std::false_type { };
81
82 template <typename T>
83 struct is_future< Future<T> > : public std::true_type { };
84
85 /// maps type \c T to \c Future<T>.
86
87 /// \tparam T The type to have future added.
88 template <typename T>
89 struct add_future {
90 /// Type with \c Future added.
91 typedef Future<T> type;
92 };
93
94 /// maps \c Future<T> to \c Future<T>.
95
96 /// Specialization of \c add_future<T> that properly forbids the type
97 /// \c Future< Future<T> >.
98 /// \tparam T The underlying data type.
99 template <typename T>
100 struct add_future< Future<T> > {
101 /// Type with \c Future added.
103 };
104
105 /// maps \c Future<T> to \c T.
106
107 /// \tparam T The type to have future removed; in this case, do nothing.
108 template <typename T>
110 /// Type with \c Future removed.
111 typedef T type;
112 };
113
114 /// This metafunction maps \c Future<T> to \c T.
115
116 /// \internal Future is a wrapper for T (it acts like an Identity monad), so this
117 /// unwraps T. It makes sense that the result should preserve the access traits
118 /// of the Future, i.e. const Future<T> should map to const T, etc.
119
120 /// Specialization of \c remove_future for \c Future<T>
121 /// \tparam T The type to have future removed.
122 template <typename T>
123 struct remove_future< Future<T> > {
124 /// Type with \c Future removed.
125 typedef T type;
126 };
127
128 /// Specialization of \c remove_future for \c Future<T>
129 /// \tparam T The type to have future removed.
130 template <typename T>
131 struct remove_future< const Future<T> > {
132 /// Type with \c Future removed.
133 typedef const T type;
134 };
135
136 /// Specialization of \c remove_future for \c Future<T>&
137 /// \tparam T The type to have future removed.
138 template <typename T>
139 struct remove_future< Future<T>& > {
140 /// Type with \c Future removed.
141 typedef T& type;
142 };
143
144 /// Specialization of \c remove_future for \c Future<T>&&
145 /// \tparam T The type to have future removed.
146 template <typename T>
147 struct remove_future< Future<T>&& > {
148 /// Type with \c Future removed.
149 typedef T&& type;
150 };
151
152 /// Specialization of \c remove_future for \c const \c Future<T>&
153 /// \tparam T The type to have future removed.
154 template <typename T>
155 struct remove_future< const Future<T>& > {
156 /// Type with \c Future removed.
157 typedef const T& type;
158 };
159
160 /// Macro to determine type of future (by removing wrapping \c Future template).
161
162 /// \param T The type (possibly with \c Future).
163 #define REMFUTURE(T) typename remove_future< T >::type
164
165 /// C++11 version of REMFUTURE
166 template <typename T>
168
169 /// Similar to remove_future , but future_to_ref<Future<T>> evaluates to T& ,whereas
170 /// remove_future<Future<T>> evaluates to T .
171 /// \tparam T The type to have future removed; in this case, do nothing.
172 template <typename T>
174 typedef T type;
175 };
176 template <typename T>
178 typedef T& type;
179 };
180 template <typename T>
182 typedef T& type;
183 };
184 template <typename T>
186 typedef T& type;
187 };
188 template <typename T>
189 struct future_to_ref<const Future<T>&> {
190 typedef T& type;
191 };
192 template <typename T>
194
195
196 // Remove Future, const, volatile, and reference qualifiers from the type
197 template <typename T>
198 struct remove_fcvr {
199 typedef typename remove_future<typename std::remove_cv<
200 typename std::remove_reference<T>::type>::type>::type type;
201 };
202 template <typename T>
204
205 /// is true type if \p T is a pointer to a free function
206 template <typename T, typename Enabler = void> struct is_function_pointer : public std::false_type {};
207 template <typename T> struct is_function_pointer<T, std::enable_if_t<std::is_function<typename std::remove_pointer<T>::type>::value>> : public std::true_type {};
208 template <typename T> constexpr bool is_function_pointer_v = is_function_pointer<T>::value;
209
210 // use std::is_member_function_pointer<T> if looking for is_member_function_pointer
211
212 /// is true type if \p T is a pointer to free or member function
213 template <typename T, typename Enabler = void> struct is_any_function_pointer : public std::false_type {};
214 template <typename T> struct is_any_function_pointer<T, std::enable_if_t<std::is_member_function_pointer<T>::value || is_function_pointer_v<T>>> : public std::true_type {};
215 template <typename T> constexpr bool is_any_function_pointer_v = is_any_function_pointer<T>::value;
216
217 /// trait for trivial (=bitwise) copyability of T, defaults to std::is_trivially_copyable<T> but can be specialized as needed
218 template <typename T>
219 struct is_trivially_copyable : std::is_trivially_copyable<T> {};
220
221 template <typename T>
223
224 /// This defines stuff that is serializable by bitwise copy.
225 /// \warning This reports true for \c T that is an aggregate type
226 /// (struct or array) that includes pointers.
227 template <typename T>
229 static const bool value = \
230 std::is_arithmetic<T>::value || \
231 std::is_function<T>::value || \
232 is_any_function_pointer_v<T> || \
233 (std::is_standard_layout<T>::value && std::is_trivial<T>::value && !std::is_pointer<T>::value);
234// ((std::is_class<T>::value || std::is_array<T>::value) && std::is_trivially_copyable<T>::value);
235 };
236
237 template <typename T>
239
240 // namespace hiding implementation details of is_ostreammable ... by ensuring that the detector lives in a different namespace branch than the operators we do not accidentally pick them up
241 namespace is_ostreammable_ns {
242
243 template <typename To, typename From> using left_shift = decltype(std::declval<To>() << std::declval<From>());
244 template <typename To, typename From> using left_shift_in_ns_madness_operators = decltype(madness::operators::operator<<(std::declval<To>(), std::declval<From>()));
245
246 template <typename T> struct impl : public meta::disjunction<meta::is_detected_exact<std::ostream&, left_shift, std::ostream&, std::add_const_t<std::add_lvalue_reference_t<T>>>,
247 meta::is_detected_exact<std::ostream&, left_shift_in_ns_madness_operators, std::ostream&, std::add_const_t<std::add_lvalue_reference_t<T>>>> {};
248 } // namespace is_ostreammable_ns
249
250 /// True for types that are "serializable" to a std::ostream
251 /// \note \c operator<<(std::ostream&,const T&) must be visible via ADL or defined in namespace madness::operators
252 template <typename T>
254
255 /// Shortcut for \c is_ostreammable<T>::value
256 template <typename T> constexpr bool is_ostreammable_v = is_ostreammable<T>::value;
257
258 // namespace hiding implementation details of is_istreammable ... by ensuring that the detector lives in a different namespace branch than the operators we do not accidentally pick them up
259 namespace is_istreammable_ns {
260
261 template <typename From, typename To> using right_shift = decltype(std::declval<From>() >> std::declval<To>());
262 template <typename From, typename To> using right_shift_in_ns_madness_operators = decltype(madness::operators::operator<<(std::declval<From>(), std::declval<To>()));
263
264 template <typename T> struct impl : public meta::disjunction<meta::is_detected_exact<std::istream&, right_shift, std::istream&, std::add_lvalue_reference_t<T>>,
265 meta::is_detected_exact<std::istream&, right_shift_in_ns_madness_operators, std::istream&, std::add_lvalue_reference_t<T>>> {};
266
267 } // namespace is_istreammable_ns
268
269 /// True for types that are "deserialiable" from an std::istream
270 /// \note \c operator>>(std::ostream&,T&) must be visible via ADL or defined in namespace madness::operators
271 template <typename T>
273
274 /// Shortcut for \c is_istreammable<T>::value
275 template <typename T> constexpr bool is_istreammable_v = is_istreammable<T>::value;
276
277 /// providing automatic support for serializing to/from std streams requires bidirectional streammability
278 template <typename T> constexpr bool is_iostreammable_v = is_istreammable_v<T> && is_ostreammable_v<T>;
279
280 template <typename T> constexpr bool is_always_serializable =
281 std::is_arithmetic<T>::value || \
282 std::is_same<std::nullptr_t, typename std::remove_cv<T>::type>::value || \
283 is_any_function_pointer_v<T> || \
284 std::is_function<T>::value;
285
286 /// helps to detect that `T` has a member serialization method that
287 /// accepts single argument of type `Archive`
288 /// @note use in combination with madness::meta::is_detected_v
289 template<typename T, typename Archive>
290 using has_member_serialize_t = decltype(std::declval<T&>().serialize(std::declval<Archive&>()));
291
292 /// helps to detect that `T` has a member serialization method that
293 /// accepts one argument of type `Archive` and an unsigned version
294 /// @note use in combination with madness::meta::is_detected_v
295 template<typename T, typename Archive>
296 using has_member_serialize_with_version_t = decltype(std::declval<T&>().serialize(std::declval<Archive&>(),0u));
297
298 /// helps to detect that `T` supports nonintrusive symmetric serialization
299 /// @note use in combination with madness::meta::is_detected_v
300 template<typename T, typename Archive>
301 using has_nonmember_serialize_t = decltype(madness::archive::ArchiveSerializeImpl<Archive, T>::serialize(std::declval<Archive&>(), std::declval<T&>()));
302
303 /// helps to detect that `T` supports nonintrusive asymmetric serialization via load
304 /// @note use in combination with madness::meta::is_detected_v
305 template<typename T, typename Archive>
306 using has_nonmember_load_t = decltype(madness::archive::ArchiveLoadImpl<Archive, T>::load(std::declval<Archive&>(), std::declval<T&>()));
307
308 /// helps to detect that `T` supports nonintrusive asymmetric serialization via store
309 /// @note use in combination with madness::meta::is_detected_v
310 template<typename T, typename Archive>
311 using has_nonmember_store_t = decltype(madness::archive::ArchiveStoreImpl<Archive, T>::store(std::declval<Archive&>(), std::declval<T&>()));
312
313 /// helps to detect that `T` supports nonintrusive asymmetric serialization via wrap_load
314 /// @note use in combination with madness::meta::is_detected_v
315 template<typename T, typename Archive>
316 using has_nonmember_wrap_load_t = decltype(madness::archive::ArchiveImpl<Archive, T>::wrap_load(std::declval<Archive&>(), std::declval<T&>()));
317
318 /// helps to detect that `T` supports nonintrusive asymmetric serialization via wrap_store
319 /// @note use in combination with madness::meta::is_detected_v
320 template<typename T, typename Archive>
321 using has_nonmember_wrap_store_t = decltype(madness::archive::ArchiveImpl<Archive, T>::wrap_store(std::declval<Archive&>(), std::declval<T&>()));
322
323 /// helps to detect that `T` supports freestanding `serialize` function
324 /// @note use in combination with madness::meta::is_detected_v
325 template<typename T, typename Archive>
326 using has_freestanding_serialize_t = decltype(serialize(std::declval<Archive&>(), std::declval<T&>()));
327
328 /// helps to detect that `T=U*` supports freestanding `serialize` function
329 /// @note use in combination with madness::meta::is_detected_v
330 template<typename T, typename Archive, typename = std::enable_if_t<std::is_pointer_v<T>>>
331 using has_freestanding_serialize_with_size_t = decltype(serialize(std::declval<Archive&>(), std::declval<T&>(), 1u));
332
333 /// helps to detect that `T` supports freestanding `serialize` function that accepts version
334 /// @note use in combination with madness::meta::is_detected_v
335 template<typename T, typename Archive, typename = std::enable_if_t<!std::is_pointer_v<T>>>
336 using has_freestanding_serialize_with_version_t = decltype(serialize(std::declval<Archive&>(), std::declval<T&>(), 0u));
337
338 /// helps to detect that `T` supports freestanding `default_serialize` function
339 /// @note use in combination with madness::meta::is_detected_v
340 template<typename T, typename Archive>
341 using has_freestanding_default_serialize_t = decltype(default_serialize(std::declval<Archive&>(), std::declval<T&>()));
342
343 /// helps to detect that `T=U*` supports freestanding `default_serialize` function
344 /// @note use in combination with madness::meta::is_detected_v
345 template<typename T, typename Archive, typename = std::enable_if_t<std::is_pointer_v<T>>>
346 using has_freestanding_default_serialize_with_size_t = decltype(default_serialize(std::declval<Archive&>(), std::declval<const T&>(), 1u));
347
348 /// true if this is well-formed:
349 /// \code
350 /// // T t; Archive ar;
351 /// t.serialize(ar);
352 /// \endcode
353 template <typename T, typename Archive>
354 inline constexpr bool has_member_serialize_v = madness::meta::is_detected_v<madness::has_member_serialize_t,T,Archive>;
355
356 /// true if this is well-formed:
357 /// \code
358 /// // T t; Archive ar;
359 /// t.serialize(ar, 0u);
360 /// \endcode
361 template <typename T, typename Archive>
362 inline constexpr bool has_member_serialize_with_version_v = madness::meta::is_detected_v<madness::has_member_serialize_with_version_t,T,Archive>;
363
364 /// true if this is well-formed:
365 /// \code
366 /// // T t; Archive ar;
367 /// madness::archive::ArchiveSerializeImpl<Archive, T>::serialize(ar, t);
368 /// \endcode
369 template <typename T, typename Archive>
370 inline constexpr bool has_nonmember_serialize_v = madness::meta::is_detected_v<madness::has_nonmember_serialize_t,T,Archive>;
371
372 /// true if this is well-formed:
373 /// \code
374 /// // T t; Archive ar;
375 /// madness::archive::ArchiveLoadImpl<Archive, T>::load(ar, t);
376 /// \endcode
377 template <typename T, typename Archive>
378 inline constexpr bool has_nonmember_load_v = madness::meta::is_detected_v<madness::has_nonmember_load_t,T,Archive>;
379
380 /// true if this is well-formed:
381 /// \code
382 /// // T t; Archive ar;
383 /// madness::archive::ArchiveStoreImpl<Archive, T>::store(ar, t);
384 /// \endcode
385 template <typename T, typename Archive>
386 inline constexpr bool has_nonmember_store_v = madness::meta::is_detected_v<madness::has_nonmember_store_t,T,Archive>;
387
388 template <typename T, typename Archive>
389 inline constexpr bool has_nonmember_load_and_store_v = has_nonmember_load_v<T, Archive> && has_nonmember_store_v<T, Archive>;
390
391 /// true if this is well-formed:
392 /// \code
393 /// // T t; Archive ar;
394 /// madness::archive::ArchiveImpl<Archive, T>::wrap_load(ar, t);
395 /// \endcode
396 template <typename T, typename Archive>
397 inline constexpr bool has_nonmember_wrap_load_v = madness::meta::is_detected_v<madness::has_nonmember_wrap_load_t,T,Archive>;
398
399 /// true if this is well-formed:
400 /// \code
401 /// // T t; Archive ar;
402 /// madness::archive::ArchiveImpl<Archive, T>::wrap_store(ar, t);
403 /// \endcode
404 template <typename T, typename Archive>
405 inline constexpr bool has_nonmember_wrap_store_v = madness::meta::is_detected_v<madness::has_nonmember_wrap_store_t,T,Archive>;
406
407 template <typename T, typename Archive>
408 inline constexpr bool has_nonmember_wrap_load_and_store_v = has_nonmember_wrap_load_v<T, Archive> && has_nonmember_wrap_store_v<T, Archive>;
409
410 /// true if this is well-formed:
411 /// \code
412 /// // T t; Archive ar;
413 /// serialize(ar, t);
414 /// \endcode
415 template <typename T, typename Archive>
416 inline constexpr bool has_freestanding_serialize_v = madness::meta::is_detected_v<madness::has_freestanding_serialize_t,T,Archive>;
417
418 /// true if this is well-formed:
419 /// \code
420 /// // T t; Archive ar;
421 /// serialize(ar, &t, 1u);
422 /// \endcode
423 template <typename T, typename Archive>
424 inline constexpr bool has_freestanding_serialize_with_size_v = madness::meta::is_detected_v<madness::has_freestanding_serialize_with_size_t,T,Archive>;
425
426 /// true if this is well-formed:
427 /// \code
428 /// // T t; Archive ar;
429 /// serialize(ar, t, 0u);
430 /// \endcode
431 template <typename T, typename Archive>
432 inline constexpr bool has_freestanding_serialize_with_version_v = madness::meta::is_detected_v<madness::has_freestanding_serialize_with_version_t,T,Archive>;
433
434 /// true if this is well-formed:
435 /// \code
436 /// // T t; Archive ar;
437 /// default_serialize(ar, t);
438 /// \endcode
439 template <typename T, typename Archive>
440 inline constexpr bool has_freestanding_default_serialize_v = madness::meta::is_detected_v<madness::has_freestanding_default_serialize_t,T,Archive>;
441
442 /// true if this is well-formed:
443 /// \code
444 /// // T t; Archive ar;
445 /// default_serialize(ar, &t, 1u);
446 /// \endcode
447 template <typename T, typename Archive>
448 inline constexpr bool has_freestanding_default_serialize_with_size_v = madness::meta::is_detected_v<madness::has_freestanding_default_serialize_with_size_t,T,Archive>;
449
450 template <typename Archive, typename T, typename Enabler = void>
451 struct is_default_serializable_helper : public std::false_type {};
452
453 /// \brief is \c std::true_type if \c T can be serialized to \c Archive
454 /// without specialized \c serialize() method
455 ///
456 /// For text stream-based \c Archive this is \c std::true_type if \c is_iostreammable<T>::value is true.
457 /// For other \c Archive types this is \c std::true_type if \c is_trivially_serializable<T>::value is true.
458 /// \tparam Archive an Archive type
459 /// \tparam T a type
460 template <typename Archive, typename T>
462 static constexpr bool value = is_default_serializable_helper<std::remove_cv_t<std::remove_reference_t<Archive>>,std::remove_cv_t<std::remove_reference_t<T>>>::value;
463 };
464
465 template <typename Archive, typename T>
467
468 template <typename Archive, typename T>
469 inline constexpr bool is_default_serializable_v<Archive, const T> = is_default_serializable_v<Archive, T>;
470
471 // forward declare archives to provide archive-specific overloads
472 namespace archive {
473 class BaseArchive;
474 class BaseInputArchive;
475 class BaseOutputArchive;
476 class BinaryFstreamOutputArchive;
477 class BinaryFstreamInputArchive;
478 class BufferOutputArchive;
479 class BufferInputArchive;
480 class VectorOutputArchive;
481 class VectorInputArchive;
482 class TextFstreamOutputArchive;
483 class TextFstreamInputArchive;
484 class MPIRawOutputArchive;
485 class MPIRawInputArchive;
486 class MPIOutputArchive;
487 class MPIInputArchive;
488 class ContainerRecordInputArchive;
489 class ContainerRecordOutputArchive;
490 template <class localarchiveT>
491 class ParallelOutputArchive;
492 template <class localarchiveT>
493 class ParallelInputArchive;
494 template <typename T>
495 class archive_array;
496 } // namespace archive
497
498 /// Checks if \c T is an archive type.
499
500 /// If \c T is an archive type, then \c is_archive will be inherited
501 /// from \c std::true_type, otherwise it is inherited from
502 /// \c std::false_type.
503 /// \tparam T The type to check.
504 /// \note define for your custom MADNESS archive type
505 template <typename T, typename Enabler = void>
507
508 template <typename T>
510
511 template <typename T>
512 inline constexpr bool is_archive_v = meta::is_detected_v<is_archive_defined_t,T>;
513
514
515 /// Checks if \c T is an input archive type.
516
517 /// If \c T is an input archive type, then \c is_input_archive will be
518 /// inherited from \c std::true_type, otherwise it is inherited from
519 /// \c std::false_type.
520 /// \tparam T The type to check.
521 /// \note define for your custom MADNESS input archive type
522 template <typename T, typename Enabler = void>
524
525 template <typename T>
527
528 template <typename T>
529 inline constexpr bool is_input_archive_v = meta::is_detected_v<is_input_archive_defined_t, T>;
530
531 /// Checks if \c T is an output archive type.
532
533 /// If \c T is an output archive type, then \c is_output_archive will
534 /// be inherited from \c std::true_type, otherwise it is inherited from
535 /// \c std::false_type.
536 /// \tparam T The type to check.
537 /// \note define for your custom MADNESS output archive type
538 template <typename T, typename Enabler = void>
540
541 template <typename T>
543
544 template <typename T>
545 inline constexpr bool is_output_archive_v = meta::is_detected_v<is_output_archive_defined_t, T>;
546
547 template <typename T>
548 struct is_default_serializable_helper<archive::BinaryFstreamOutputArchive, T, std::enable_if_t<is_trivially_serializable<T>::value>> : std::true_type {};
549 template <typename T>
550 struct is_default_serializable_helper<archive::BinaryFstreamInputArchive, T, std::enable_if_t<is_trivially_serializable<T>::value>> : std::true_type {};
551 template <typename T>
552 struct is_default_serializable_helper<archive::BufferOutputArchive, T, std::enable_if_t<is_trivially_serializable<T>::value>> : std::true_type {};
553 template <typename T>
554 struct is_default_serializable_helper<archive::BufferInputArchive, T, std::enable_if_t<is_trivially_serializable<T>::value>> : std::true_type {};
555 template <typename T>
556 struct is_default_serializable_helper<archive::VectorOutputArchive, T, std::enable_if_t<is_trivially_serializable<T>::value>> : std::true_type {};
557 template <typename T>
558 struct is_default_serializable_helper<archive::VectorInputArchive, T, std::enable_if_t<is_trivially_serializable<T>::value>> : std::true_type {};
559 // N.B. if type can be printed but can't be read it's not serializable
560 // N.N.B. functions and function pointers will be converted to integers, hence will be always serializable
561 template <typename T>
562 struct is_default_serializable_helper<archive::TextFstreamOutputArchive, T, std::enable_if_t<is_iostreammable_v<T> || std::is_function_v<T> || is_any_function_pointer_v<T>>> : std::true_type {};
563 template <typename T>
564 struct is_default_serializable_helper<archive::TextFstreamInputArchive, T, std::enable_if_t<is_iostreammable_v<T> || is_any_function_pointer_v<T>>> : std::true_type {};
565 template <typename T>
566 struct is_default_serializable_helper<archive::MPIRawOutputArchive, T, std::enable_if_t<is_trivially_serializable<T>::value>> : std::true_type {};
567 template <typename T>
568 struct is_default_serializable_helper<archive::MPIRawInputArchive, T, std::enable_if_t<is_trivially_serializable<T>::value>> : std::true_type {};
569 template <typename T>
570 struct is_default_serializable_helper<archive::MPIOutputArchive, T, std::enable_if_t<is_trivially_serializable<T>::value>> : std::true_type {};
571 template <typename T>
572 struct is_default_serializable_helper<archive::MPIInputArchive, T, std::enable_if_t<is_trivially_serializable<T>::value>> : std::true_type {};
573 template <typename T>
574 struct is_default_serializable_helper<archive::ContainerRecordOutputArchive, T, std::enable_if_t<is_trivially_serializable<T>::value>> : std::true_type {};
575 template <typename T>
576 struct is_default_serializable_helper<archive::ContainerRecordInputArchive, T, std::enable_if_t<is_trivially_serializable<T>::value>> : std::true_type {};
577 template <typename T, class localarchiveT>
578 struct is_default_serializable_helper<archive::ParallelOutputArchive<localarchiveT>, T, std::enable_if_t<is_trivially_serializable<T>::value>> : std::true_type {};
579 template <typename T, class localarchiveT>
580 struct is_default_serializable_helper<archive::ParallelInputArchive<localarchiveT>, T, std::enable_if_t<is_trivially_serializable<T>::value>> : std::true_type {};
581 template <typename Archive, typename T>
582 struct is_default_serializable_helper<Archive, archive::archive_array<T>, std::enable_if_t<is_default_serializable_helper<Archive,T>::value>> : std::true_type {};
583
584 template <>
585 struct is_archive<archive::BinaryFstreamOutputArchive> : std::true_type {};
586 template <>
587 struct is_archive<archive::BinaryFstreamInputArchive> : std::true_type {};
588 template <>
589 struct is_archive<archive::BufferOutputArchive> : std::true_type {};
590 template <>
591 struct is_archive<archive::BufferInputArchive> : std::true_type {};
592 template <>
593 struct is_archive<archive::VectorOutputArchive> : std::true_type {};
594 template <>
595 struct is_archive<archive::VectorInputArchive> : std::true_type {};
596 template <>
597 struct is_archive<archive::TextFstreamOutputArchive> : std::true_type {};
598 template <>
599 struct is_archive<archive::TextFstreamInputArchive> : std::true_type {};
600 template <>
601 struct is_archive<archive::MPIRawOutputArchive> : std::true_type {};
602 template <>
603 struct is_archive<archive::MPIRawInputArchive> : std::true_type {};
604 template <>
605 struct is_archive<archive::MPIOutputArchive> : std::true_type {};
606 template <>
607 struct is_archive<archive::MPIInputArchive> : std::true_type {};
608 template <>
609 struct is_archive<archive::ContainerRecordOutputArchive> : std::true_type {};
610 template <>
611 struct is_archive<archive::ContainerRecordInputArchive> : std::true_type {};
612 template <class localarchiveT>
613 struct is_archive<archive::ParallelOutputArchive<localarchiveT> > : std::true_type {};
614 template <class localarchiveT>
615 struct is_archive<archive::ParallelInputArchive<localarchiveT> > : std::true_type {};
616
617 template <>
618 struct is_output_archive<archive::BinaryFstreamOutputArchive> : std::true_type {};
619 template <>
620 struct is_output_archive<archive::BufferOutputArchive> : std::true_type {};
621 template <>
622 struct is_output_archive<archive::VectorOutputArchive> : std::true_type {};
623 template <>
624 struct is_output_archive<archive::TextFstreamOutputArchive> : std::true_type {};
625 template <>
626 struct is_output_archive<archive::MPIRawOutputArchive> : std::true_type {};
627 template <>
628 struct is_output_archive<archive::MPIOutputArchive> : std::true_type {};
629 template <>
630 struct is_output_archive<archive::ContainerRecordOutputArchive> : std::true_type {};
631 template <class localarchiveT>
632 struct is_output_archive<archive::ParallelOutputArchive<localarchiveT> > : std::true_type {};
633
634 template <>
635 struct is_input_archive<archive::BinaryFstreamInputArchive> : std::true_type {};
636 template <>
637 struct is_input_archive<archive::BufferInputArchive> : std::true_type {};
638 template <>
639 struct is_input_archive<archive::VectorInputArchive> : std::true_type {};
640 template <>
641 struct is_input_archive<archive::TextFstreamInputArchive> : std::true_type {};
642 template <>
643 struct is_input_archive<archive::MPIRawInputArchive> : std::true_type {};
644 template <>
645 struct is_input_archive<archive::MPIInputArchive> : std::true_type {};
646 template <>
647 struct is_input_archive<archive::ContainerRecordInputArchive> : std::true_type {};
648 template <class localarchiveT>
649 struct is_input_archive<archive::ParallelInputArchive<localarchiveT> > : std::true_type {};
650
651 /// Evaluates to true if can serialize an object of type `T` to an object of type `Archive` using user-provided methods
652 /// \tparam Archive
653 /// \tparam T
654 template <typename Archive, typename T>
655 inline constexpr bool is_user_serializable_v = is_archive_v<Archive> && (has_member_serialize_v<T, Archive> ||
656 has_nonmember_serialize_v<T, Archive> ||
657 ((has_nonmember_load_v<T, Archive> || has_nonmember_wrap_load_v<T, Archive>) && is_input_archive_v<Archive> && !has_freestanding_default_serialize_v<T, Archive>) ||
658 ((has_nonmember_store_v<T, Archive> || has_nonmember_wrap_store_v<T, Archive>) && is_output_archive_v<Archive> && !has_freestanding_default_serialize_v<T, Archive>));
659
660 template <typename Archive, typename T>
661 inline constexpr bool is_user_serializable_v<Archive, const T> = is_user_serializable_v<Archive, T>;
662
663 /// Evaluates to true if can serialize an object of type `T` to an object of type `Archive`,
664 /// using either user-provided methods or, if `T` is default-serializable to `Archive`,
665 /// using default method for this `Archive`
666 /// \tparam Archive
667 /// \tparam T
668 template <typename Archive, typename T>
669 inline constexpr bool is_serializable_v = is_archive_v<Archive> && (is_default_serializable_v<Archive, T> ||
670 is_user_serializable_v<Archive,T>);
671
672 template <typename Archive, typename T>
673 inline constexpr bool is_serializable_v<Archive, const T> = is_serializable_v<Archive, T>;
674
675 template <typename Archive, typename T>
676 struct is_serializable : std::bool_constant<is_serializable_v<Archive,T>> {};
677
678 /// \brief This trait types tests if \c Archive is a text archive
679 /// \tparam Archive an archive type
680 /// \note much be specialized for each archive
681 template <typename Archive, typename Enabler = void>
682 struct is_text_archive : std::false_type {};
683
684 template <>
685 struct is_text_archive<archive::TextFstreamOutputArchive> : std::true_type {};
686 template <>
687 struct is_text_archive<archive::TextFstreamInputArchive> : std::true_type {};
688
689 /// \brief \c is_text_archive_v<A> is a shorthand for \c is_text_archive<A>::value
690 /// \tparam Archive an archive type
691 template <typename Archive>
693
694 /*
695 * Some traits for Functions and alike
696 */
697
698 /// next two structs loop over type and dimension
699 /// loop over N=1..6 and apply Functor<T,N> to functor_args..., then call the resulting functor with call_args...
700 /// returns array of results
701 /// Functor must be a template with two parameters: type and integer
702 /// functor_args is a tuple of arguments to be forwarded to Functor<T,N>
703 /// call_args are arguments to be forwarded to the resulting functor
704 /// Example:
705 /// \code
706 /// template<typename T, std::size_t N>
707 /// struct MyFunctor {
708 /// MyFunctor(int a, double b) : a_(a), b_(b) {}
709 /// T operator()(const std::string& s) { return T(a_ * N, b_ * N, s); }
710 /// int a_;
711 /// double b_;
712 /// };
713 /// ...
714 /// loop_types<MyFunctor, double, float, double_complex, float_complex>(std::tuple<int,double>(1,2.0),std::string("hello"));
715 /// results is std::array
716 /// \endcode
717 template<template<typename, std::size_t> class Functor, typename T, std::size_t... Is, typename... FunctorArgs, typename... CallArgs>
718 auto loop_N(std::index_sequence<Is...>, std::tuple<FunctorArgs...>&& functor_args, CallArgs&&... call_args)
719 -> std::array<decltype(Functor<T, 1>(std::forward<FunctorArgs>(std::get<FunctorArgs>(functor_args))...)(std::forward<CallArgs>(call_args)...)), sizeof...(Is)>
720 {
721 return { Functor<T, Is + 1>(std::forward<FunctorArgs>(std::get<FunctorArgs>(functor_args))...)(std::forward<CallArgs>(call_args)...)... };
722 }
723
724 template<template<typename, std::size_t> class Functor, typename... Ts, typename... FunctorArgs, typename... CallArgs>
725 auto loop_types(std::tuple<FunctorArgs...>&& functor_args, CallArgs&&... call_args)
726 {
727 return std::make_tuple(loop_N<Functor, Ts>(std::make_index_sequence<6>{}, std::move(functor_args), std::forward<CallArgs>(call_args)...)...);
728 }
729
730 /// loop over a tuple and apply unary operator op to each element
731 template<typename tupleT, typename opT, std::size_t I=0>
732 static void unary_tuple_loop(tupleT& tuple, opT& op) {
733 if constexpr(I < std::tuple_size_v<tupleT>) {
734 auto& element1=std::get<I>(tuple);
735 op(element1);
736 unary_tuple_loop<tupleT,opT, I+1>(tuple,op);
737 }
738 }
739
740 /// loop over the tuple elements of both tuples and execute the operation op on each element pair
741 template<typename tupleT, typename tupleR, typename opT, std::size_t I=0>
742 static void binary_tuple_loop(tupleT& tuple1, tupleR& tuple2, opT& op) {
743 if constexpr(I < std::tuple_size_v<tupleT>) {
744 auto& element1=std::get<I>(tuple1);
745 auto& element2=std::get<I>(tuple2);
746 op(element1,element2);
747 binary_tuple_loop<tupleT, tupleR, opT, I+1>(tuple1,tuple2,op);
748 }
749 }
750
751 /// check if objT is a std::vector of Function<T,NDIM>
752 /// forward declaration of Function
753 /// usage: is_madness_function_vector<objT>::value
754 template<typename T, std::size_t NDIM> class Function;
755 template<typename>
756 struct is_madness_function_vector : std::false_type { };
757 template<typename T, std::size_t NDIM>
758 struct is_madness_function_vector<std::vector<Function<T, NDIM>>> : std::true_type { };
759
760
761
762 /* Macros to make some of this stuff more readable */
763
764 /**
765 \def REMCONST(TYPE)
766 \brief Macro to make remove_const<T> easier to use
767
768 \def MEMFUN_RETURNT(TYPE)
769 \brief Macro to make member function type traits easier to use
770 */
771
772#define REMCONST(TYPE) typename std::remove_const< TYPE >::type
773#define MEMFUN_RETURNT(MEMFUN) typename madness::detail::memfunc_traits< MEMFUN >::result_type
774
775} // namespace madness
776
777#endif // MADNESS_WORLD_TYPE_TRAITS_H__INCLUDED
A future is a possibly yet unevaluated value.
Definition future.h:369
Definition type_traits.h:54
auto T(World &world, response_space &f) -> response_space
Definition global_functions.cc:28
static double u(double r, double c)
Definition he.cc:20
Tensor< double > op(const Tensor< double > &x)
Definition kain.cc:508
decltype(madness::operators::operator<<(std::declval< From >(), std::declval< To >())) right_shift_in_ns_madness_operators
Definition type_traits.h:262
decltype(std::declval< From >() > > std::declval< To >()) right_shift
Definition type_traits.h:261
decltype(madness::operators::operator<<(std::declval< To >(), std::declval< From >())) left_shift_in_ns_madness_operators
Definition type_traits.h:244
decltype(std::declval< To >()<< std::declval< From >()) left_shift
Definition type_traits.h:243
std::ostream & operator<<(std::ostream &s, const std::array< T, N > &a)
Output std::array to stream for human consumption.
Definition array_addons.h:59
std::ostream & operator>>(std::ostream &, __x &)
Namespace for all elements and tools of MADNESS.
Definition DFParameters.h:10
constexpr bool has_nonmember_load_and_store_v
Definition type_traits.h:389
typename future_to_ref< T >::type future_to_ref_t
Definition type_traits.h:193
auto loop_types(std::tuple< FunctorArgs... > &&functor_args, CallArgs &&... call_args)
Definition type_traits.h:725
constexpr bool is_serializable_v
Definition type_traits.h:669
typename remove_fcvr< T >::type remove_fcvr_t
Definition type_traits.h:203
constexpr bool is_always_serializable
Definition type_traits.h:280
decltype(madness::archive::ArchiveImpl< Archive, T >::wrap_load(std::declval< Archive & >(), std::declval< T & >())) has_nonmember_wrap_load_t
Definition type_traits.h:316
decltype(std::declval< T & >().serialize(std::declval< Archive & >())) has_member_serialize_t
Definition type_traits.h:290
constexpr bool is_function_pointer_v
Definition type_traits.h:208
constexpr bool is_istreammable_v
Shortcut for is_istreammable<T>::value.
Definition type_traits.h:275
decltype(serialize(std::declval< Archive & >(), std::declval< T & >(), 1u)) has_freestanding_serialize_with_size_t
Definition type_traits.h:331
constexpr bool has_nonmember_wrap_load_v
Definition type_traits.h:397
decltype(serialize(std::declval< Archive & >(), std::declval< T & >())) has_freestanding_serialize_t
Definition type_traits.h:326
constexpr bool is_default_serializable_v< Archive, const T >
Definition type_traits.h:469
constexpr bool is_user_serializable_v< Archive, const T >
Definition type_traits.h:661
constexpr bool has_member_serialize_v
Definition type_traits.h:354
constexpr bool has_freestanding_serialize_with_size_v
Definition type_traits.h:424
constexpr bool has_nonmember_wrap_load_and_store_v
Definition type_traits.h:408
decltype(default_serialize(std::declval< Archive & >(), std::declval< const T & >(), 1u)) has_freestanding_default_serialize_with_size_t
Definition type_traits.h:346
constexpr bool has_freestanding_serialize_with_version_v
Definition type_traits.h:432
constexpr bool has_freestanding_serialize_v
Definition type_traits.h:416
decltype(madness::archive::ArchiveSerializeImpl< Archive, T >::serialize(std::declval< Archive & >(), std::declval< T & >())) has_nonmember_serialize_t
Definition type_traits.h:301
constexpr bool is_iostreammable_v
providing automatic support for serializing to/from std streams requires bidirectional streammability
Definition type_traits.h:278
constexpr bool is_user_serializable_v
Definition type_traits.h:655
typename is_input_archive< std::remove_reference_t< std::remove_cv_t< T > > >::type is_input_archive_defined_t
Definition type_traits.h:526
decltype(madness::archive::ArchiveLoadImpl< Archive, T >::load(std::declval< Archive & >(), std::declval< T & >())) has_nonmember_load_t
Definition type_traits.h:306
constexpr bool is_ostreammable_v
Shortcut for is_ostreammable<T>::value.
Definition type_traits.h:256
typename is_archive< std::remove_reference_t< std::remove_cv_t< T > > >::type is_archive_defined_t
Definition type_traits.h:509
typename is_output_archive< std::remove_reference_t< std::remove_cv_t< T > > >::type is_output_archive_defined_t
Definition type_traits.h:542
constexpr bool is_default_serializable_v
Definition type_traits.h:466
static void binary_tuple_loop(tupleT &tuple1, tupleR &tuple2, opT &op)
loop over the tuple elements of both tuples and execute the operation op on each element pair
Definition type_traits.h:742
decltype(default_serialize(std::declval< Archive & >(), std::declval< T & >())) has_freestanding_default_serialize_t
Definition type_traits.h:341
constexpr bool is_output_archive_v
Definition type_traits.h:545
static void unary_tuple_loop(tupleT &tuple, opT &op)
loop over a tuple and apply unary operator op to each element
Definition type_traits.h:732
constexpr bool has_nonmember_wrap_store_v
Definition type_traits.h:405
constexpr bool has_freestanding_default_serialize_v
Definition type_traits.h:440
auto loop_N(std::index_sequence< Is... >, std::tuple< FunctorArgs... > &&functor_args, CallArgs &&... call_args) -> std::array< decltype(Functor< T, 1 >(std::forward< FunctorArgs >(std::get< FunctorArgs >(functor_args))...)(std::forward< CallArgs >(call_args)...)), sizeof...(Is)>
Definition type_traits.h:718
constexpr bool is_any_function_pointer_v
Definition type_traits.h:215
decltype(serialize(std::declval< Archive & >(), std::declval< T & >(), 0u)) has_freestanding_serialize_with_version_t
Definition type_traits.h:336
constexpr bool is_input_archive_v
Definition type_traits.h:529
constexpr bool has_member_serialize_with_version_v
Definition type_traits.h:362
std::string type(const PairType &n)
Definition PNOParameters.h:18
decltype(madness::archive::ArchiveStoreImpl< Archive, T >::store(std::declval< Archive & >(), std::declval< T & >())) has_nonmember_store_t
Definition type_traits.h:311
constexpr bool has_nonmember_serialize_v
Definition type_traits.h:370
decltype(std::declval< T & >().serialize(std::declval< Archive & >(), 0u)) has_member_serialize_with_version_t
Definition type_traits.h:296
constexpr bool is_serializable_v< Archive, const T >
Definition type_traits.h:673
constexpr bool has_nonmember_store_v
Definition type_traits.h:386
constexpr bool is_archive_v
Definition type_traits.h:512
constexpr const bool is_text_archive_v
is_text_archive_v is a shorthand for is_text_archive<A>::value
Definition type_traits.h:692
decltype(madness::archive::ArchiveImpl< Archive, T >::wrap_store(std::declval< Archive & >(), std::declval< T & >())) has_nonmember_wrap_store_t
Definition type_traits.h:321
constexpr bool has_nonmember_load_v
Definition type_traits.h:378
typename remove_future< T >::type remove_future_t
C++11 version of REMFUTURE.
Definition type_traits.h:167
constexpr bool is_trivially_copyable_v
Definition type_traits.h:222
constexpr bool has_freestanding_default_serialize_with_size_v
Definition type_traits.h:448
constexpr bool is_trivially_serializable_v
Definition type_traits.h:238
Definition mraimpl.h:51
Future< T > type
Type with Future added.
Definition type_traits.h:102
maps type T to Future<T>.
Definition type_traits.h:89
Future< T > type
Type with Future added.
Definition type_traits.h:91
static const Archive & wrap_load(const Archive &ar, const T &t)
Load an object sandwiched between its preamble and postamble.
Definition archive.h:748
static const Archive & wrap_store(const Archive &ar, const T &t)
Store an object sandwiched between its preamble and postamble.
Definition archive.h:734
static void load(const A &ar, const U &t)
Load an object.
Definition archive.h:679
static void serialize(const Archive &ar, T &t)
Serializes the type.
Definition archive.h:561
static std::enable_if_t< is_output_archive_v< A > &&!std::is_function< U >::value &&(has_member_serialize_v< U, A >||has_nonmember_serialize_v< U, A >||has_freestanding_serialize_v< U, A >||has_freestanding_default_serialize_v< U, A >), void > store(const A &ar, const U &t)
Definition archive.h:622
T & type
Definition type_traits.h:178
T & type
Definition type_traits.h:182
T & type
Definition type_traits.h:186
T & type
Definition type_traits.h:190
Definition type_traits.h:173
T type
Definition type_traits.h:174
is true type if T is a pointer to free or member function
Definition type_traits.h:213
Checks if T is an archive type.
Definition type_traits.h:506
Definition type_traits.h:451
is std::true_type if T can be serialized to Archive without specialized serialize() method
Definition type_traits.h:461
static constexpr bool value
Definition type_traits.h:462
is true type if T is a pointer to a free function
Definition type_traits.h:206
test if a type is a future.
Definition type_traits.h:80
Checks if T is an input archive type.
Definition type_traits.h:523
Definition type_traits.h:265
Definition type_traits.h:272
Definition type_traits.h:756
Definition type_traits.h:247
Definition type_traits.h:253
Checks if T is an output archive type.
Definition type_traits.h:539
Definition type_traits.h:676
This trait types tests if Archive is a text archive.
Definition type_traits.h:682
trait for trivial (=bitwise) copyability of T, defaults to std::is_trivially_copyable<T> but can be s...
Definition type_traits.h:219
Definition type_traits.h:228
static const bool value
Definition type_traits.h:229
Definition meta.h:29
Definition type_traits.h:198
remove_future< typenamestd::remove_cv< typenamestd::remove_reference< T >::type >::type >::type type
Definition type_traits.h:200
T type
Type with Future removed.
Definition type_traits.h:125
T & type
Type with Future removed.
Definition type_traits.h:141
T && type
Type with Future removed.
Definition type_traits.h:149
const T type
Type with Future removed.
Definition type_traits.h:133
const T & type
Type with Future removed.
Definition type_traits.h:157
maps Future<T> to T.
Definition type_traits.h:109
T type
Type with Future removed.
Definition type_traits.h:111