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/fusion/support/config.hpp>
13 #include <boost/config.hpp>
18 // Tuple I/O manipulators
20 #define FUSION_GET_CHAR_TYPE(T) typename T::char_type
21 #define FUSION_GET_TRAITS_TYPE(T) typename T::traits_type
23 #define FUSION_STRING_OF_STREAM(Stream) \
25 FUSION_GET_CHAR_TYPE(Stream) \
26 , FUSION_GET_TRAITS_TYPE(Stream) \
29 //$$$ these should be part of the public API$$$
30 //$$$ rename tuple_open, tuple_close and tuple_delimiter to
31 // open, close and delimeter and add these synonyms to the
34 namespace boost { namespace fusion
38 template <typename Tag>
39 int get_xalloc_index(Tag* = 0)
41 // each Tag will have a unique index
42 static int index = std::ios::xalloc();
46 template <typename Stream, typename Tag, typename T>
54 typename std::vector<T*>::iterator i = data.begin()
65 static void attach(Stream& stream, T const& data)
67 static arena ar; // our arena
68 ar.data.push_back(new T(data));
69 stream.pword(get_xalloc_index<Tag>()) = ar.data.back();
72 static T const* get(Stream& stream)
74 return (T const*)stream.pword(get_xalloc_index<Tag>());
78 template <typename Tag, typename Stream>
79 class string_ios_manip
83 typedef FUSION_STRING_OF_STREAM(Stream) string_type;
85 typedef stream_data<Stream, Tag, string_type> stream_data_t;
87 string_ios_manip(Stream& str_)
92 set(string_type const& s)
94 stream_data_t::attach(stream, s);
98 print(char const* default_) const
101 string_type const* p = stream_data_t::get(stream);
109 read(char const* default_) const
112 string_type const* p = stream_data_t::get(stream);
117 typedef typename string_type::const_iterator iterator;
118 for (iterator i = p->begin(); i != p->end(); ++i)
124 check_delim(*default_++);
130 template <typename Char>
132 check_delim(Char c) const
136 if (stream.get() != c)
139 stream.setstate(std::ios::failbit);
147 // silence MSVC warning C4512: assignment operator could not be generated
148 string_ios_manip& operator= (string_ios_manip const&);
154 #if defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
156 #define STD_TUPLE_DEFINE_MANIPULATOR_FUNCTIONS(name) \
157 template <typename Char, typename Traits> \
158 inline detail::name##_type<Char, Traits> \
159 name(const std::basic_string<Char, Traits>& s) \
161 return detail::name##_type<Char, Traits>(s); \
164 inline detail::name##_type<char> \
165 name(char const* s) \
167 return detail::name##_type<char>(std::basic_string<char>(s)); \
170 inline detail::name##_type<wchar_t> \
171 name(wchar_t const* s) \
173 return detail::name##_type<wchar_t>(std::basic_string<wchar_t>(s)); \
176 inline detail::name##_type<char> \
179 return detail::name##_type<char>(std::basic_string<char>(1, c)); \
182 inline detail::name##_type<wchar_t> \
185 return detail::name##_type<wchar_t>(std::basic_string<wchar_t>(1, c)); \
188 #else // defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
190 #define STD_TUPLE_DEFINE_MANIPULATOR_FUNCTIONS(name) \
191 template <typename Char, typename Traits> \
192 inline detail::name##_type<Char, Traits> \
193 name(const std::basic_string<Char, Traits>& s) \
195 return detail::name##_type<Char, Traits>(s); \
198 template <typename Char> \
199 inline detail::name##_type<Char> \
202 return detail::name##_type<Char>(std::basic_string<Char>(s)); \
205 template <typename Char> \
206 inline detail::name##_type<Char> \
207 name(Char const s[]) \
209 return detail::name##_type<Char>(std::basic_string<Char>(s)); \
212 template <typename Char> \
213 inline detail::name##_type<Char> \
216 return detail::name##_type<Char>(std::basic_string<Char>(1, c)); \
221 #define STD_TUPLE_DEFINE_MANIPULATOR(name) \
226 template <typename Char, typename Traits = std::char_traits<Char> > \
229 typedef std::basic_string<Char, Traits> string_type; \
231 name##_type(const string_type& d): data(d) {} \
234 template <typename Stream, typename Char, typename Traits> \
235 Stream& operator>>(Stream& s, const name##_type<Char,Traits>& m) \
237 string_ios_manip<name##_tag, Stream> manip(s); \
242 template <typename Stream, typename Char, typename Traits> \
243 Stream& operator<<(Stream& s, const name##_type<Char,Traits>& m) \
245 string_ios_manip<name##_tag, Stream> manip(s); \
252 STD_TUPLE_DEFINE_MANIPULATOR(tuple_open)
253 STD_TUPLE_DEFINE_MANIPULATOR(tuple_close)
254 STD_TUPLE_DEFINE_MANIPULATOR(tuple_delimiter)
256 STD_TUPLE_DEFINE_MANIPULATOR_FUNCTIONS(tuple_open)
257 STD_TUPLE_DEFINE_MANIPULATOR_FUNCTIONS(tuple_close)
258 STD_TUPLE_DEFINE_MANIPULATOR_FUNCTIONS(tuple_delimiter)
260 #undef STD_TUPLE_DEFINE_MANIPULATOR
261 #undef STD_TUPLE_DEFINE_MANIPULATOR_FUNCTIONS
262 #undef FUSION_STRING_OF_STREAM
263 #undef FUSION_GET_CHAR_TYPE
264 #undef FUSION_GET_TRAITS_TYPE