blob: 515eb074f387eb3ba4a65c195a0fe3d656fe0f18 [file] [log] [blame]
Jeff Thompson86b6d642013-10-17 15:01:56 -07001// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
2// (C) Copyright 2003-2007 Jonathan Turkanis
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// See http://www.boost.org/libs/iostreams for documentation.
7
8//
9// Contains metafunctions char_type_of, category_of and mode_of used for
10// deducing the i/o category and i/o mode of a model of Filter or Device.
11//
12// Also contains several utility metafunctions, functions and macros.
13//
14
15#ifndef NDNBOOST_IOSTREAMS_IO_TRAITS_HPP_INCLUDED
16#define NDNBOOST_IOSTREAMS_IO_TRAITS_HPP_INCLUDED
17
18#if defined(_MSC_VER) && (_MSC_VER >= 1020)
19# pragma once
20#endif
21
22#include <iosfwd> // stream types, char_traits.
23#include <ndnboost/config.hpp> // partial spec, deduced typename.
24#include <ndnboost/detail/workaround.hpp>
25#include <ndnboost/iostreams/categories.hpp>
26#include <ndnboost/iostreams/detail/bool_trait_def.hpp>
27#include <ndnboost/iostreams/detail/config/wide_streams.hpp>
28#include <ndnboost/iostreams/detail/is_iterator_range.hpp>
29#include <ndnboost/iostreams/detail/select.hpp>
30#include <ndnboost/iostreams/detail/select_by_size.hpp>
31#include <ndnboost/iostreams/detail/wrap_unwrap.hpp>
32#include <ndnboost/iostreams/traits_fwd.hpp>
33#include <ndnboost/mpl/bool.hpp>
34#include <ndnboost/mpl/eval_if.hpp>
35#include <ndnboost/mpl/identity.hpp>
36#include <ndnboost/mpl/int.hpp>
37#include <ndnboost/mpl/or.hpp>
38#if !NDNBOOST_WORKAROUND(NDNBOOST_MSVC, <= 1300)
39# include <ndnboost/range/iterator_range.hpp>
40# include <ndnboost/range/value_type.hpp>
41#endif // #if NDNBOOST_WORKAROUND(NDNBOOST_MSVC, <= 1300)
42#include <ndnboost/ref.hpp>
43#include <ndnboost/type_traits/is_convertible.hpp>
44
45// Must come last.
46#include <ndnboost/iostreams/detail/config/disable_warnings.hpp>
47
48namespace ndnboost { namespace iostreams {
49
50//----------Definitions of predicates for streams and stream buffers----------//
51
52#ifndef NDNBOOST_IOSTREAMS_NO_STREAM_TEMPLATES //--------------------------------//
53
54NDNBOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_istream, std::basic_istream, 2)
55NDNBOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_ostream, std::basic_ostream, 2)
56NDNBOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_iostream, std::basic_iostream, 2)
57NDNBOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_streambuf, std::basic_streambuf, 2)
58NDNBOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_ifstream, std::basic_ifstream, 2)
59NDNBOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_ofstream, std::basic_ofstream, 2)
60NDNBOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_fstream, std::basic_fstream, 2)
61NDNBOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_filebuf, std::basic_filebuf, 2)
62NDNBOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_istringstream, std::basic_istringstream, 3)
63NDNBOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_ostringstream, std::basic_ostringstream, 3)
64NDNBOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_stringstream, std::basic_stringstream, 3)
65NDNBOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_stringbuf, std::basic_stringbuf, 3)
66
67#else // #ifndef NDNBOOST_IOSTREAMS_NO_STREAM_TEMPLATES //-----------------------//
68
69NDNBOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_istream, std::istream, 0)
70NDNBOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_ostream, std::ostream, 0)
71NDNBOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_iostream, std::iostream, 0)
72NDNBOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_streambuf, std::streambuf, 0)
73
74#endif // #ifndef NDNBOOST_IOSTREAMS_NO_STREAM_TEMPLATES //----------------------//
75
76template<typename T>
77struct is_std_io
78 : mpl::or_< is_istream<T>, is_ostream<T>, is_streambuf<T> >
79 { };
80
81template<typename T>
82struct is_std_file_device
83 : mpl::or_<
84 is_ifstream<T>,
85 is_ofstream<T>,
86 is_fstream<T>,
87 is_filebuf<T>
88 >
89 { };
90
91template<typename T>
92struct is_std_string_device
93 : mpl::or_<
94 is_istringstream<T>,
95 is_ostringstream<T>,
96 is_stringstream<T>,
97 is_stringbuf<T>
98 >
99 { };
100
101template<typename Device, typename Tr, typename Alloc>
102struct stream;
103
104template<typename T, typename Tr, typename Alloc, typename Mode>
105class stream_buffer;
106
107template< typename Mode, typename Ch, typename Tr,
108 typename Alloc, typename Access >
109class filtering_stream;
110
111template< typename Mode, typename Ch, typename Tr,
112 typename Alloc, typename Access >
113class wfiltering_stream;
114
115template< typename Mode, typename Ch, typename Tr,
116 typename Alloc, typename Access >
117class filtering_streambuf;
118
119template< typename Mode, typename Ch, typename Tr,
120 typename Alloc, typename Access >
121class filtering_wstreambuf;
122
123namespace detail {
124
125template<typename T, typename Tr>
126class linked_streambuf;
127
128NDNBOOST_IOSTREAMS_BOOL_TRAIT_DEF( is_boost_stream,
129 ndnboost::iostreams::stream,
130 3 )
131NDNBOOST_IOSTREAMS_BOOL_TRAIT_DEF( is_boost_stream_buffer,
132 ndnboost::iostreams::stream_buffer,
133 4 )
134NDNBOOST_IOSTREAMS_BOOL_TRAIT_DEF( is_filtering_stream_impl,
135 ndnboost::iostreams::filtering_stream,
136 5 )
137NDNBOOST_IOSTREAMS_BOOL_TRAIT_DEF( is_filtering_wstream_impl,
138 ndnboost::iostreams::wfiltering_stream,
139 5 )
140NDNBOOST_IOSTREAMS_BOOL_TRAIT_DEF( is_filtering_streambuf_impl,
141 ndnboost::iostreams::filtering_streambuf,
142 5 )
143NDNBOOST_IOSTREAMS_BOOL_TRAIT_DEF( is_filtering_wstreambuf_impl,
144 ndnboost::iostreams::filtering_wstreambuf,
145 5 )
146NDNBOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_linked, linked_streambuf, 2)
147
148template<typename T>
149struct is_filtering_stream
150 : mpl::or_<
151 is_filtering_stream_impl<T>,
152 is_filtering_wstream_impl<T>
153 >
154 { };
155
156template<typename T>
157struct is_filtering_streambuf
158 : mpl::or_<
159 is_filtering_streambuf_impl<T>,
160 is_filtering_wstreambuf_impl<T>
161 >
162 { };
163
164template<typename T>
165struct is_boost
166 : mpl::or_<
167 is_boost_stream<T>,
168 is_boost_stream_buffer<T>,
169 is_filtering_stream<T>,
170 is_filtering_streambuf<T>
171 >
172 { };
173
174} // End namespace detail.
175
176//------------------Definitions of char_type_of-------------------------------//
177
178namespace detail {
179
180template<typename T>
181struct member_char_type { typedef typename T::char_type type; };
182
183} // End namespace detail.
184
185#ifndef NDNBOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION //---------------------------//
186# ifndef NDNBOOST_IOSTREAMS_NO_STREAM_TEMPLATES //-------------------------------//
187
188template<typename T>
189struct char_type_of
190 : detail::member_char_type<
191 typename detail::unwrapped_type<T>::type
192 >
193 { };
194
195# else // # ifndef NDNBOOST_IOSTREAMS_NO_STREAM_TEMPLATES //---------------------//
196
197template<typename T>
198struct char_type_of {
199 typedef typename detail::unwrapped_type<T>::type U;
200 typedef typename
201 mpl::eval_if<
202 is_std_io<U>,
203 mpl::identity<char>,
204 detail::member_char_type<U>
205 >::type type;
206};
207
208# endif // # ifndef NDNBOOST_IOSTREAMS_NO_STREAM_TEMPLATES //--------------------//
209
210template<typename Iter>
211struct char_type_of< iterator_range<Iter> > {
212 typedef typename iterator_value<Iter>::type type;
213};
214
215#else // #ifndef NDNBOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION //------------------//
216
217template<typename T>
218struct char_type_of {
219 template<typename U>
220 struct get_value_type {
221 #if !NDNBOOST_WORKAROUND(NDNBOOST_MSVC, <= 1300)
222 typedef typename range_value<U>::type type;
223 #endif // #if NDNBOOST_WORKAROUND(NDNBOOST_MSVC, <= 1300)
224 };
225 typedef typename
226 mpl::eval_if<
227 is_iterator_range<T>,
228 get_value_type<T>,
229 detail::member_char_type<
230 NDNBOOST_DEDUCED_TYPENAME detail::unwrapped_type<T>::type
231 >
232 >::type type;
233};
234
235#endif // #ifndef NDNBOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION //-----------------//
236
237//------------------Definitions of category_of--------------------------------//
238
239namespace detail {
240
241template<typename T>
242struct member_category { typedef typename T::category type; };
243
244} // End namespace detail.
245
246template<typename T>
247struct category_of {
248 template<typename U>
249 struct member_category {
250 typedef typename U::category type;
251 };
252 typedef typename detail::unwrapped_type<T>::type U;
253 typedef typename
254 mpl::eval_if<
255 mpl::and_<
256 is_std_io<U>,
257 mpl::not_< detail::is_boost<U> >
258 >,
259 iostreams::select< // Disambiguation for Tru64
260 is_filebuf<U>, filebuf_tag,
261 is_ifstream<U>, ifstream_tag,
262 is_ofstream<U>, ofstream_tag,
263 is_fstream<U>, fstream_tag,
264 is_stringbuf<U>, stringbuf_tag,
265 is_istringstream<U>, istringstream_tag,
266 is_ostringstream<U>, ostringstream_tag,
267 is_stringstream<U>, stringstream_tag,
268 is_streambuf<U>, generic_streambuf_tag,
269 is_iostream<U>, generic_iostream_tag,
270 is_istream<U>, generic_istream_tag,
271 is_ostream<U>, generic_ostream_tag
272 >,
273 detail::member_category<U>
274 >::type type;
275};
276
277// Partial specialization for reference wrappers
278#ifndef NDNBOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION //---------------------------//
279
280template<typename T>
281struct category_of< reference_wrapper<T> >
282 : category_of<T>
283 { };
284
285#endif // #ifndef NDNBOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION //-----------------//
286
287//------------------Definition of get_category--------------------------------//
288
289//
290// Returns an object of type category_of<T>::type.
291//
292template<typename T>
293inline typename category_of<T>::type get_category(const T&)
294{ typedef typename category_of<T>::type category; return category(); }
295
296//------------------Definition of int_type_of---------------------------------//
297
298template<typename T>
299struct int_type_of {
300#ifndef NDNBOOST_IOSTREAMS_NO_STREAM_TEMPLATES
301 typedef std::char_traits<
302 NDNBOOST_DEDUCED_TYPENAME char_type_of<T>::type
303 > traits_type;
304 typedef typename traits_type::int_type type;
305#else
306 typedef int type;
307#endif
308};
309
310//------------------Definition of mode_of-------------------------------------//
311
312namespace detail {
313
314template<int N> struct io_mode_impl;
315
316#define NDNBOOST_IOSTREAMS_MODE_HELPER(tag_, id_) \
317 case_<id_> io_mode_impl_helper(tag_); \
318 template<> struct io_mode_impl<id_> { typedef tag_ type; }; \
319 /**/
320NDNBOOST_IOSTREAMS_MODE_HELPER(input, 1)
321NDNBOOST_IOSTREAMS_MODE_HELPER(output, 2)
322NDNBOOST_IOSTREAMS_MODE_HELPER(bidirectional, 3)
323NDNBOOST_IOSTREAMS_MODE_HELPER(input_seekable, 4)
324NDNBOOST_IOSTREAMS_MODE_HELPER(output_seekable, 5)
325NDNBOOST_IOSTREAMS_MODE_HELPER(seekable, 6)
326NDNBOOST_IOSTREAMS_MODE_HELPER(dual_seekable, 7)
327NDNBOOST_IOSTREAMS_MODE_HELPER(bidirectional_seekable, 8)
328NDNBOOST_IOSTREAMS_MODE_HELPER(dual_use, 9)
329#undef NDNBOOST_IOSTREAMS_MODE_HELPER
330
331template<typename T>
332struct io_mode_id {
333 typedef typename category_of<T>::type category;
334 NDNBOOST_SELECT_BY_SIZE(int, value, detail::io_mode_impl_helper(category()));
335};
336
337} // End namespace detail.
338
339template<typename T> // Borland 5.6.4 requires this circumlocution.
340struct mode_of : detail::io_mode_impl< detail::io_mode_id<T>::value > { };
341
342// Partial specialization for reference wrappers
343#ifndef NDNBOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION //---------------------------//
344
345template<typename T>
346struct mode_of< reference_wrapper<T> >
347 : mode_of<T>
348 { };
349
350#endif // #ifndef NDNBOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION //-----------------//
351
352//------------------Definition of is_device, is_filter and is_direct----------//
353
354namespace detail {
355
356template<typename T, typename Tag>
357struct has_trait_impl {
358 typedef typename category_of<T>::type category;
359 NDNBOOST_STATIC_CONSTANT(bool, value = (is_convertible<category, Tag>::value));
360};
361
362template<typename T, typename Tag>
363struct has_trait
364 : mpl::bool_<has_trait_impl<T, Tag>::value>
365 { };
366
367} // End namespace detail.
368
369template<typename T>
370struct is_device : detail::has_trait<T, device_tag> { };
371
372template<typename T>
373struct is_filter : detail::has_trait<T, filter_tag> { };
374
375template<typename T>
376struct is_direct : detail::has_trait<T, direct_tag> { };
377
378//------------------Definition of NDNBOOST_IOSTREAMS_STREAMBUF_TYPEDEFS----------//
379
380#define NDNBOOST_IOSTREAMS_STREAMBUF_TYPEDEFS(Tr) \
381 typedef Tr traits_type; \
382 typedef typename traits_type::int_type int_type; \
383 typedef typename traits_type::off_type off_type; \
384 typedef typename traits_type::pos_type pos_type; \
385 /**/
386
387} } // End namespaces iostreams, boost.
388
389#include <ndnboost/iostreams/detail/config/enable_warnings.hpp>
390
391#endif // #ifndef NDNBOOST_IOSTREAMS_IO_TRAITS_HPP_INCLUDED