1 /*=============================================================================
2 Copyright (c) 1999-2003 Jeremiah Willcock
3 Copyright (c) 1999-2003 Jaakko Jarvi
4 Copyright (c) 2001-2011 Joel de Guzman
6 Distributed under the Boost Software License, Version 1.0. (See accompanying
7 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8 ==============================================================================*/
9 #if !defined(FUSION_MANIP_05052005_1200)
10 #define FUSION_MANIP_05052005_1200
12 #include <boost/config.hpp>
17 // Tuple I/O manipulators
19 #define FUSION_GET_CHAR_TYPE(T) typename T::char_type
20 #define FUSION_GET_TRAITS_TYPE(T) typename T::traits_type
22 #if defined (BOOST_NO_TEMPLATED_STREAMS)
23 #define FUSION_STRING_OF_STREAM(Stream) std::string
25 #define FUSION_STRING_OF_STREAM(Stream) \
27 FUSION_GET_CHAR_TYPE(Stream) \
28 , FUSION_GET_TRAITS_TYPE(Stream) \
32 //$$$ these should be part of the public API$$$
33 //$$$ rename tuple_open, tuple_close and tuple_delimiter to
34 // open, close and delimeter and add these synonyms to the
37 namespace boost { namespace fusion
41 template <typename Tag>
42 int get_xalloc_index(Tag* = 0)
44 // each Tag will have a unique index
45 static int index = std::ios::xalloc();
49 template <typename Stream, typename Tag, typename T>
57 typename std::vector<T*>::iterator i = data.begin()
68 static void attach(Stream& stream, T const& data)
70 static arena ar; // our arena
71 ar.data.push_back(new T(data));
72 stream.pword(get_xalloc_index<Tag>()) = ar.data.back();
75 static T const* get(Stream& stream)
77 return (T const*)stream.pword(get_xalloc_index<Tag>());
81 template <typename Tag, typename Stream>
82 class string_ios_manip
86 typedef FUSION_STRING_OF_STREAM(Stream) string_type;
88 typedef stream_data<Stream, Tag, string_type> stream_data_t;
90 string_ios_manip(Stream& str_)
95 set(string_type const& s)
97 stream_data_t::attach(stream, s);
101 print(char const* default_) const
104 string_type const* p = stream_data_t::get(stream);
112 read(char const* default_) const
115 string_type const* p = stream_data_t::get(stream);
121 typedef typename string_type::const_iterator iterator;
122 for (iterator i = p->begin(); i != p->end(); ++i)
128 check_delim(*default_++);
134 template <typename Char>
136 check_delim(Char c) const
140 if (stream.get() != c)
143 stream.setstate(std::ios::failbit);
151 // silence MSVC warning C4512: assignment operator could not be generated
152 string_ios_manip& operator= (string_ios_manip const&);
157 #if defined (BOOST_NO_TEMPLATED_STREAMS)
159 #define STD_TUPLE_DEFINE_MANIPULATOR(name) \
166 typedef std::string string_type; \
168 name##_type(const string_type& d): data(d) {} \
171 template <typename Stream> \
172 Stream& operator>>(Stream& s, const name##_type& m) \
174 string_ios_manip<name##_tag, Stream>(s).set(m.data); \
178 template <typename Stream> \
179 Stream& operator<<(Stream& s, const name##_type& m) \
181 string_ios_manip<name##_tag, Stream>(s).set(m.data); \
186 #define STD_TUPLE_DEFINE_MANIPULATOR_FUNCTIONS(name) \
187 inline detail::name##_type \
188 name(const std::string& s) \
190 return detail::name##_type(s); \
193 inline detail::name##_type \
194 name(const char* s) \
196 return detail::name##_type(std::string(s)); \
199 inline detail::name##_type \
202 return detail::name##_type(std::string(1, c)); \
205 #else // defined(BOOST_NO_TEMPLATED_STREAMS)
207 #if defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
209 #define STD_TUPLE_DEFINE_MANIPULATOR_FUNCTIONS(name) \
210 template <typename Char, typename Traits> \
211 inline detail::name##_type<Char, Traits> \
212 name(const std::basic_string<Char, Traits>& s) \
214 return detail::name##_type<Char, Traits>(s); \
217 inline detail::name##_type<char> \
218 name(char const* s) \
220 return detail::name##_type<char>(std::basic_string<char>(s)); \
223 inline detail::name##_type<wchar_t> \
224 name(wchar_t const* s) \
226 return detail::name##_type<wchar_t>(std::basic_string<wchar_t>(s)); \
229 inline detail::name##_type<char> \
232 return detail::name##_type<char>(std::basic_string<char>(1, c)); \
235 inline detail::name##_type<wchar_t> \
238 return detail::name##_type<wchar_t>(std::basic_string<wchar_t>(1, c)); \
241 #else // defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
243 #define STD_TUPLE_DEFINE_MANIPULATOR_FUNCTIONS(name) \
244 template <typename Char, typename Traits> \
245 inline detail::name##_type<Char, Traits> \
246 name(const std::basic_string<Char, Traits>& s) \
248 return detail::name##_type<Char, Traits>(s); \
251 template <typename Char> \
252 inline detail::name##_type<Char> \
255 return detail::name##_type<Char>(std::basic_string<Char>(s)); \
258 template <typename Char> \
259 inline detail::name##_type<Char> \
260 name(Char const s[]) \
262 return detail::name##_type<Char>(std::basic_string<Char>(s)); \
265 template <typename Char> \
266 inline detail::name##_type<Char> \
269 return detail::name##_type<Char>(std::basic_string<Char>(1, c)); \
274 #define STD_TUPLE_DEFINE_MANIPULATOR(name) \
279 template <typename Char, typename Traits = std::char_traits<Char> > \
282 typedef std::basic_string<Char, Traits> string_type; \
284 name##_type(const string_type& d): data(d) {} \
287 template <typename Stream, typename Char, typename Traits> \
288 Stream& operator>>(Stream& s, const name##_type<Char,Traits>& m) \
290 string_ios_manip<name##_tag, Stream>(s).set(m.data); \
294 template <typename Stream, typename Char, typename Traits> \
295 Stream& operator<<(Stream& s, const name##_type<Char,Traits>& m) \
297 string_ios_manip<name##_tag, Stream>(s).set(m.data); \
302 #endif // defined(BOOST_NO_TEMPLATED_STREAMS)
304 STD_TUPLE_DEFINE_MANIPULATOR(tuple_open)
305 STD_TUPLE_DEFINE_MANIPULATOR(tuple_close)
306 STD_TUPLE_DEFINE_MANIPULATOR(tuple_delimiter)
308 STD_TUPLE_DEFINE_MANIPULATOR_FUNCTIONS(tuple_open)
309 STD_TUPLE_DEFINE_MANIPULATOR_FUNCTIONS(tuple_close)
310 STD_TUPLE_DEFINE_MANIPULATOR_FUNCTIONS(tuple_delimiter)
312 #undef STD_TUPLE_DEFINE_MANIPULATOR
313 #undef STD_TUPLE_DEFINE_MANIPULATOR_FUNCTIONS
314 #undef FUSION_STRING_OF_STREAM
315 #undef FUSION_GET_CHAR_TYPE
316 #undef FUSION_GET_TRAITS_TYPE