TPIE

11a2c2d
stream_writable.h
1 // -*- mode: c++; tab-width: 4; indent-tabs-mode: t; eval: (progn (c-set-style "stroustrup") (c-set-offset 'innamespace 0)); -*-
2 // vi:set ts=4 sts=4 sw=4 noet :
3 // Copyright 2013, The TPIE development team
4 //
5 // This file is part of TPIE.
6 //
7 // TPIE is free software: you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License as published by the
9 // Free Software Foundation, either version 3 of the License, or (at your
10 // option) any later version.
11 //
12 // TPIE is distributed in the hope that it will be useful, but WITHOUT ANY
13 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 // License for more details.
16 //
17 // You should have received a copy of the GNU Lesser General Public License
18 // along with TPIE. If not, see <http://www.gnu.org/licenses/>
19 
20 #ifndef __TPIE_STREAM_WRITABLE_H__
21 #define __TPIE_STREAM_WRITABLE_H__
22 #include <type_traits>
23 #include <utility>
24 #include <iostream>
25 #include <tuple>
26 
27 namespace tpie {
28 
29 /*
30  * We require that the item type T of a file_stream to be trivially copyable.
31  *
32  * However std::pair<T1, T2> is not required by the standard to be trivially copyable
33  * when T1 and T2 are trivially copyable.
34  * Only the copy constructors are required to be trivial,
35  * but not the assignment operators.
36  * This means that no compiler implements std::pair with trivial assignment operators.
37  *
38  * For more info see: https://en.cppreference.com/w/cpp/named_req/TriviallyCopyable
39  *
40  * So instead of writing our own implementation of std::pair and forcing everyone who uses a file_stream to use it,
41  * we relax this condition for std::pair and std::tuple, even though this is undefined behaviour.
42  */
43 template <typename T>
45 private:
46  template <typename TT>
47  static char magic(typename TT::trivially_copyable*);
48 
49  template <typename TT>
50  static char magic(typename TT::stream_writable*);
51 
52  template <typename TT>
53  static long magic(...);
54 public:
55  static bool const value=sizeof(magic<T>((std::true_type*)nullptr))==sizeof(char);
56 };
57 
58 template <typename ... TT>
60 
61 template <>
62 struct is_stream_writable<>: std::integral_constant<bool, true> {};
63 
64 template <typename T1, typename T2, typename ... TT>
65 struct is_stream_writable<T1, T2, TT...>:
66  std::integral_constant<bool, is_stream_writable<T1>::value && is_stream_writable<T2, TT...>::value> {};
67 
68 template <typename T>
69 struct is_stream_writable<T> :
70  std::integral_constant<bool, std::is_trivially_copyable<T>::value || is_stream_writable_override<T>::value> {};
71 
72 template <typename T1, typename T2>
73 struct is_stream_writable<std::pair<T1, T2>> : is_stream_writable<T1, T2> {};
74 
75 template <typename ... TT>
76 struct is_stream_writable<std::tuple<TT...>> : is_stream_writable<TT...> {};
77 
78 } //namespace tpie
79 #endif //__TPIE_STREAM_WRITABLE_H__
tpie::is_stream_writable_override
Definition: stream_writable.h:44
tpie::is_stream_writable
Definition: stream_writable.h:59
tpie
Definition: access_type.h:26