]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com) |
2 | // (C) Copyright 2004-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 | #ifndef BOOST_IOSTREAMS_ARRAY_HPP_INCLUDED | |
9 | #define BOOST_IOSTREAMS_ARRAY_HPP_INCLUDED | |
10 | ||
11 | #if defined(_MSC_VER) | |
12 | # pragma once | |
13 | #endif | |
14 | ||
15 | #include <boost/config.hpp> // BOOST_MSVC, make sure size_t is in std. | |
16 | #include <boost/detail/workaround.hpp> | |
17 | #include <cstddef> // std::size_t. | |
18 | #include <utility> // pair. | |
19 | #include <boost/iostreams/categories.hpp> | |
20 | #include <boost/preprocessor/cat.hpp> | |
21 | #include <boost/static_assert.hpp> | |
22 | #include <boost/type_traits/is_convertible.hpp> | |
23 | #include <boost/type_traits/is_same.hpp> | |
24 | ||
25 | namespace boost { namespace iostreams { | |
26 | ||
27 | namespace detail { | |
28 | ||
29 | template<typename Mode, typename Ch> | |
30 | class array_adapter { | |
31 | public: | |
32 | typedef Ch char_type; | |
33 | typedef std::pair<char_type*, char_type*> pair_type; | |
34 | struct category | |
35 | : public Mode, | |
36 | public device_tag, | |
37 | public direct_tag | |
38 | { }; | |
39 | array_adapter(char_type* begin, char_type* end); | |
40 | array_adapter(char_type* begin, std::size_t length); | |
41 | array_adapter(const char_type* begin, const char_type* end); | |
42 | array_adapter(const char_type* begin, std::size_t length); | |
43 | template<int N> | |
44 | array_adapter(char_type (&ar)[N]) | |
45 | : begin_(ar), end_(ar + N) | |
46 | { } | |
47 | pair_type input_sequence(); | |
48 | pair_type output_sequence(); | |
49 | private: | |
50 | char_type* begin_; | |
51 | char_type* end_; | |
52 | }; | |
53 | ||
54 | } // End namespace detail. | |
55 | ||
56 | #define BOOST_IOSTREAMS_ARRAY(name, mode) \ | |
57 | template<typename Ch> \ | |
58 | struct BOOST_PP_CAT(basic_, name) : detail::array_adapter<mode, Ch> { \ | |
59 | private: \ | |
60 | typedef detail::array_adapter<mode, Ch> base_type; \ | |
61 | public: \ | |
62 | typedef typename base_type::char_type char_type; \ | |
63 | typedef typename base_type::category category; \ | |
64 | BOOST_PP_CAT(basic_, name)(char_type* begin, char_type* end) \ | |
65 | : base_type(begin, end) { } \ | |
66 | BOOST_PP_CAT(basic_, name)(char_type* begin, std::size_t length) \ | |
67 | : base_type(begin, length) { } \ | |
68 | BOOST_PP_CAT(basic_, name)(const char_type* begin, const char_type* end) \ | |
69 | : base_type(begin, end) { } \ | |
70 | BOOST_PP_CAT(basic_, name)(const char_type* begin, std::size_t length) \ | |
71 | : base_type(begin, length) { } \ | |
72 | template<int N> \ | |
73 | BOOST_PP_CAT(basic_, name)(Ch (&ar)[N]) \ | |
74 | : base_type(ar) { } \ | |
75 | }; \ | |
76 | typedef BOOST_PP_CAT(basic_, name)<char> name; \ | |
77 | typedef BOOST_PP_CAT(basic_, name)<wchar_t> BOOST_PP_CAT(w, name); \ | |
78 | /**/ | |
79 | BOOST_IOSTREAMS_ARRAY(array_source, input_seekable) | |
80 | BOOST_IOSTREAMS_ARRAY(array_sink, output_seekable) | |
81 | BOOST_IOSTREAMS_ARRAY(array, seekable) | |
82 | #undef BOOST_IOSTREAMS_ARRAY | |
83 | ||
84 | ||
85 | //------------------Implementation of array_adapter---------------------------// | |
86 | ||
87 | namespace detail { | |
88 | ||
89 | template<typename Mode, typename Ch> | |
90 | array_adapter<Mode, Ch>::array_adapter | |
91 | (char_type* begin, char_type* end) | |
92 | : begin_(begin), end_(end) | |
93 | { } | |
94 | ||
95 | template<typename Mode, typename Ch> | |
96 | array_adapter<Mode, Ch>::array_adapter | |
97 | (char_type* begin, std::size_t length) | |
98 | : begin_(begin), end_(begin + length) | |
99 | { } | |
100 | ||
101 | template<typename Mode, typename Ch> | |
102 | array_adapter<Mode, Ch>::array_adapter | |
103 | (const char_type* begin, const char_type* end) | |
104 | : begin_(const_cast<char_type*>(begin)), // Treated as read-only. | |
105 | end_(const_cast<char_type*>(end)) // Treated as read-only. | |
106 | { BOOST_STATIC_ASSERT((!is_convertible<Mode, output>::value)); } | |
107 | ||
108 | template<typename Mode, typename Ch> | |
109 | array_adapter<Mode, Ch>::array_adapter | |
110 | (const char_type* begin, std::size_t length) | |
111 | : begin_(const_cast<char_type*>(begin)), // Treated as read-only. | |
112 | end_(const_cast<char_type*>(begin) + length) // Treated as read-only. | |
113 | { BOOST_STATIC_ASSERT((!is_convertible<Mode, output>::value)); } | |
114 | ||
115 | template<typename Mode, typename Ch> | |
116 | typename array_adapter<Mode, Ch>::pair_type | |
117 | array_adapter<Mode, Ch>::input_sequence() | |
118 | { BOOST_STATIC_ASSERT((is_convertible<Mode, input>::value)); | |
119 | return pair_type(begin_, end_); } | |
120 | ||
121 | template<typename Mode, typename Ch> | |
122 | typename array_adapter<Mode, Ch>::pair_type | |
123 | array_adapter<Mode, Ch>::output_sequence() | |
124 | { BOOST_STATIC_ASSERT((is_convertible<Mode, output>::value)); | |
125 | return pair_type(begin_, end_); } | |
126 | ||
127 | } // End namespace detail. | |
128 | ||
129 | //----------------------------------------------------------------------------// | |
130 | ||
131 | } } // End namespaces iostreams, boost. | |
132 | ||
133 | #endif // #ifndef BOOST_IOSTREAMS_ARRAY_HPP_INCLUDED |