1 | // (C) Copyright Jonathan Turkanis 2004. |
---|
2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
---|
3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.) |
---|
4 | |
---|
5 | // See http://www.boost.org/libs/iostreams for documentation. |
---|
6 | |
---|
7 | #ifndef BOOST_IOSTREAMS_ARRAY_HPP_INCLUDED |
---|
8 | #define BOOST_IOSTREAMS_ARRAY_HPP_INCLUDED |
---|
9 | |
---|
10 | #if defined(_MSC_VER) && (_MSC_VER >= 1020) |
---|
11 | # pragma once |
---|
12 | #endif |
---|
13 | |
---|
14 | #include <boost/config.hpp> // BOOST_MSVC, make sure size_t is in std. |
---|
15 | #include <boost/detail/workaround.hpp> |
---|
16 | #include <cstddef> // std::size_t. |
---|
17 | #include <utility> // pair. |
---|
18 | #include <boost/iostreams/categories.hpp> |
---|
19 | #include <boost/preprocessor/cat.hpp> |
---|
20 | #include <boost/static_assert.hpp> |
---|
21 | #include <boost/type_traits/is_convertible.hpp> |
---|
22 | #include <boost/type_traits/is_same.hpp> |
---|
23 | |
---|
24 | namespace boost { namespace iostreams { |
---|
25 | |
---|
26 | namespace detail { |
---|
27 | |
---|
28 | template<typename Mode, typename Ch> |
---|
29 | class array_adapter { |
---|
30 | public: |
---|
31 | typedef Ch char_type; |
---|
32 | typedef std::pair<char_type*, char_type*> pair_type; |
---|
33 | struct category |
---|
34 | : public Mode, |
---|
35 | public device_tag, |
---|
36 | public direct_tag |
---|
37 | { }; |
---|
38 | array_adapter(char_type* begin, char_type* end); |
---|
39 | array_adapter(char_type* begin, std::size_t length); |
---|
40 | array_adapter(const char_type* begin, const char_type* end); |
---|
41 | array_adapter(const char_type* begin, std::size_t length); |
---|
42 | #if !BOOST_WORKAROUND(BOOST_MSVC, < 1300) |
---|
43 | template<int N> |
---|
44 | array_adapter(char_type (&ar)[N]) |
---|
45 | : begin_(ar), end_(ar + N) |
---|
46 | { } |
---|
47 | #endif |
---|
48 | pair_type input_sequence(); |
---|
49 | pair_type output_sequence(); |
---|
50 | private: |
---|
51 | char_type* begin_; |
---|
52 | char_type* end_; |
---|
53 | }; |
---|
54 | |
---|
55 | } // End namespace detail. |
---|
56 | |
---|
57 | // Local macros, #undef'd below. |
---|
58 | #if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) |
---|
59 | # define BOOST_IOSTREAMS_ARRAY_CTOR(name, ch) \ |
---|
60 | template<int N> \ |
---|
61 | BOOST_PP_CAT(basic_, name)(ch (&ar)[N]) \ |
---|
62 | : base_type(ar) { } \ |
---|
63 | /**/ |
---|
64 | #else |
---|
65 | # define BOOST_IOSTREAMS_ARRAY_CTOR(name, ch) |
---|
66 | #endif |
---|
67 | #define BOOST_IOSTREAMS_ARRAY(name, mode) \ |
---|
68 | template<typename Ch> \ |
---|
69 | struct BOOST_PP_CAT(basic_, name) : detail::array_adapter<mode, Ch> { \ |
---|
70 | private: \ |
---|
71 | typedef detail::array_adapter<mode, Ch> base_type; \ |
---|
72 | public: \ |
---|
73 | typedef typename base_type::char_type char_type; \ |
---|
74 | typedef typename base_type::category category; \ |
---|
75 | BOOST_PP_CAT(basic_, name)(char_type* begin, char_type* end) \ |
---|
76 | : base_type(begin, end) { } \ |
---|
77 | BOOST_PP_CAT(basic_, name)(char_type* begin, std::size_t length) \ |
---|
78 | : base_type(begin, length) { } \ |
---|
79 | BOOST_PP_CAT(basic_, name)(const char_type* begin, const char_type* end) \ |
---|
80 | : base_type(begin, end) { } \ |
---|
81 | BOOST_PP_CAT(basic_, name)(const char_type* begin, std::size_t length) \ |
---|
82 | : base_type(begin, length) { } \ |
---|
83 | BOOST_IOSTREAMS_ARRAY_CTOR(name, Ch) \ |
---|
84 | }; \ |
---|
85 | typedef BOOST_PP_CAT(basic_, name)<char> name; \ |
---|
86 | typedef BOOST_PP_CAT(basic_, name)<wchar_t> BOOST_PP_CAT(w, name); \ |
---|
87 | /**/ |
---|
88 | BOOST_IOSTREAMS_ARRAY(array_source, input_seekable) |
---|
89 | BOOST_IOSTREAMS_ARRAY(array_sink, output_seekable) |
---|
90 | BOOST_IOSTREAMS_ARRAY(array, seekable) |
---|
91 | #undef BOOST_IOSTREAMS_ARRAY_CTOR |
---|
92 | #undef BOOST_IOSTREAMS_ARRAY |
---|
93 | |
---|
94 | |
---|
95 | //------------------Implementation of array_adapter---------------------------// |
---|
96 | |
---|
97 | namespace detail { |
---|
98 | |
---|
99 | template<typename Mode, typename Ch> |
---|
100 | array_adapter<Mode, Ch>::array_adapter |
---|
101 | (char_type* begin, char_type* end) |
---|
102 | : begin_(begin), end_(end) |
---|
103 | { } |
---|
104 | |
---|
105 | template<typename Mode, typename Ch> |
---|
106 | array_adapter<Mode, Ch>::array_adapter |
---|
107 | (char_type* begin, std::size_t length) |
---|
108 | : begin_(begin), end_(begin + length) |
---|
109 | { } |
---|
110 | |
---|
111 | template<typename Mode, typename Ch> |
---|
112 | array_adapter<Mode, Ch>::array_adapter |
---|
113 | (const char_type* begin, const char_type* end) |
---|
114 | : begin_(const_cast<char_type*>(begin)), // Treated as read-only. |
---|
115 | end_(const_cast<char_type*>(end)) // Treated as read-only. |
---|
116 | { BOOST_STATIC_ASSERT((!is_convertible<Mode, output>::value)); } |
---|
117 | |
---|
118 | template<typename Mode, typename Ch> |
---|
119 | array_adapter<Mode, Ch>::array_adapter |
---|
120 | (const char_type* begin, std::size_t length) |
---|
121 | : begin_(const_cast<char_type*>(begin)), // Treated as read-only. |
---|
122 | end_(const_cast<char_type*>(begin) + length) // Treated as read-only. |
---|
123 | { BOOST_STATIC_ASSERT((!is_convertible<Mode, output>::value)); } |
---|
124 | |
---|
125 | template<typename Mode, typename Ch> |
---|
126 | typename array_adapter<Mode, Ch>::pair_type |
---|
127 | array_adapter<Mode, Ch>::input_sequence() |
---|
128 | { BOOST_STATIC_ASSERT((is_convertible<Mode, input>::value)); |
---|
129 | return pair_type(begin_, end_); } |
---|
130 | |
---|
131 | template<typename Mode, typename Ch> |
---|
132 | typename array_adapter<Mode, Ch>::pair_type |
---|
133 | array_adapter<Mode, Ch>::output_sequence() |
---|
134 | { BOOST_STATIC_ASSERT((is_convertible<Mode, output>::value)); |
---|
135 | return pair_type(begin_, end_); } |
---|
136 | |
---|
137 | } // End namespace detail. |
---|
138 | |
---|
139 | //----------------------------------------------------------------------------// |
---|
140 | |
---|
141 | } } // End namespaces iostreams, boost. |
---|
142 | |
---|
143 | #endif // #ifndef BOOST_IOSTREAMS_ARRAY_HPP_INCLUDED |
---|