TPIE

2362a60
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  * but we relax this condition for std::pair, std::tuple
32  *
33  * std::pair<T1, T2> is not required by the standard to be trivially copyable
34  * if T1 and T2 are trivially copyable.
35  * This means that no compiler implements std::pair so it is trivially copyable in that case.
36  *
37  * To avoid having to write our own implementation of std::pair and require everybody who uses a file_stream to use it.
38  * The standard requires that the copy constructor on the std::pair be default, so memcopying it is not undefined behaviour.
39  */
40 template <typename T>
42 private:
43  template <typename TT>
44  static char magic(typename TT::trivially_copyable*);
45 
46  template <typename TT>
47  static char magic(typename TT::stream_writable*);
48 
49  template <typename TT>
50  static long magic(...);
51 public:
52  static bool const value=sizeof(magic<T>((std::true_type*)nullptr))==sizeof(char);
53 };
54 
55 template <typename ... TT>
57 
58 template <>
59 struct is_stream_writable<>: std::integral_constant<bool, true> {};
60 
61 template <typename T1, typename T2, typename ... TT>
62 struct is_stream_writable<T1, T2, TT...>:
63  std::integral_constant<bool, is_stream_writable<T1>::value && is_stream_writable<T2, TT...>::value> {};
64 
65 template <typename T>
66 struct is_stream_writable<T> :
67  std::integral_constant<bool, std::is_trivially_copyable<T>::value || is_stream_writable_override<T>::value> {};
68 
69 template <typename T1, typename T2>
70 struct is_stream_writable<std::pair<T1, T2>> : is_stream_writable<T1, T2> {};
71 
72 template <typename ... TT>
73 struct is_stream_writable<std::tuple<TT...>> : is_stream_writable<TT...> {};
74 
75 } //namespace tpie
76 #endif //__TPIE_STREAM_WRITABLE_H__