echelon  0.8.0
container_adaption.hpp
1 // Copyright (c) 2012-2014 Christopher Hinz
2 //
3 // Distributed under the Boost Software License, Version 1.0. (See accompanying
4 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5 
6 #ifndef ECHELON_HDF5_CONTAINER_ADAPTION_HPP
7 #define ECHELON_HDF5_CONTAINER_ADAPTION_HPP
8 
9 #include <utility>
10 #include <type_traits>
11 
12 namespace echelon
13 {
14 namespace hdf5
15 {
16 
17 struct adl_enabler
18 {
19 };
20 
21 // Note: Due to a bug in the Intel compiler, it is important that the overloads are
22 // declared in this specific order.
23 
24 template <typename C>
25 inline auto data(C&& container) -> decltype(data(container, adl_enabler{}))
26 {
27  return data(container, adl_enabler{});
28 }
29 
30 template <typename C>
31 inline auto data(C&& container) -> decltype(container.data())
32 {
33  return container.data();
34 }
35 
36 // Function template which simply forwards its arguments to an overload of
37 // shape.
38 // Its sole purpose is to ensure that the correct overload can be found by ADL.
39 template <typename C>
40 inline auto data_adl(C&& container) -> decltype(data(container))
41 {
42  return data(container);
43 }
44 
45 template <typename C>
46 inline auto shape(const C& container) -> decltype(shape(container, adl_enabler{}))
47 {
48  return shape(container, adl_enabler{});
49 }
50 
51 template <typename C>
52 inline auto shape(const C& container) -> decltype(container.shape())
53 {
54  return container.shape();
55 }
56 
57 template <typename C>
58 inline auto shape_adl(const C& container) -> decltype(shape(container))
59 {
60  return shape(container);
61 }
62 
63 template <typename C>
64 inline auto reshape(C& container, const std::vector<std::size_t>& new_shape)
65  -> decltype(reshape(container, new_shape, adl_enabler{}))
66 {
67  return reshape(container, new_shape, adl_enabler{});
68 }
69 
77 template <typename C>
78 inline auto reshape(C& container, const std::vector<std::size_t>& new_shape)
79  -> decltype(container.reshape(new_shape))
80 {
81  return container.reshape(new_shape);
82 }
83 
84 template <typename C>
85 inline auto reshape_adl(C& container, const std::vector<std::size_t>& new_shape)
86  -> decltype(reshape(container, new_shape))
87 {
88  return reshape(container, new_shape);
89 }
90 
91 namespace detail
92 {
93 
94 template <typename T>
95 constexpr auto has_data_accessor_impl(int) -> decltype((data_adl(std::declval<T>()), bool{}))
96 {
97  return true;
98 }
99 
100 template <typename T>
101 constexpr bool has_data_accessor_impl(...)
102 {
103  return false;
104 }
105 
106 template <typename T>
107 constexpr auto has_shape_property_impl(int) -> decltype((shape(std::declval<T>()), bool{}))
108 {
109  return true;
110 }
111 
112 template <typename T>
113 constexpr bool has_shape_property_impl(...)
114 {
115  return false;
116 }
117 
118 template <typename T>
119 constexpr auto has_reshape_member_impl(int)
120  -> decltype((reshape(std::declval<T&>(), std::vector<std::size_t>{}), bool{}))
121 {
122  return true;
123 }
124 
125 template <typename T>
126 constexpr bool has_reshape_member_impl(...)
127 {
128  return false;
129 }
130 }
131 
132 template <typename T>
133 constexpr bool has_data_accessor()
134 {
135  return detail::has_data_accessor_impl<T>(0);
136 }
137 
138 template <typename T>
139 constexpr bool has_shape_property()
140 {
141  return detail::has_shape_property_impl<T>(0);
142 }
143 
144 template <typename T>
145 constexpr bool has_reshape_member()
146 {
147  return detail::has_reshape_member_impl<T>(0);
148 }
149 
150 template <typename T>
151 constexpr bool is_readable_container()
152 {
153  return has_data_accessor<const T>() && has_shape_property<T>();
154 }
155 
156 template <typename T>
157 constexpr bool is_container()
158 {
159  return has_data_accessor<T>() && has_shape_property<T>();
160 }
161 
162 
163 template <typename C>
164 struct container_trait
165 {
166  static_assert(is_container<C>(), "C does not fulfill the Container requirements.");
167 
168  using value_type = typename std::decay<decltype(*data_adl(std::declval<const C>()))>::type;
169 };
170 
171 }
172 }
173 
174 #endif
echelon&#39;s core namespace
Definition: attribute.cpp:10
auto reshape(C &container, const std::vector< std::size_t > &new_shape) -> decltype(reshape(container, new_shape, adl_enabler
Reshapes the container.
Definition: container_adaption.hpp:64
A handle to an HDF5 type.
Definition: hdf5/type.hpp:23