Chris@16: /*============================================================================= Chris@16: Copyright (c) 1999-2003 Jeremiah Willcock Chris@16: Copyright (c) 1999-2003 Jaakko Jarvi Chris@16: Copyright (c) 2001-2011 Joel de Guzman Chris@16: Chris@16: Distributed under the Boost Software License, Version 1.0. (See accompanying Chris@16: file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@16: ==============================================================================*/ Chris@16: #if !defined(FUSION_MANIP_05052005_1200) Chris@16: #define FUSION_MANIP_05052005_1200 Chris@16: Chris@101: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: // Tuple I/O manipulators Chris@16: Chris@16: #define FUSION_GET_CHAR_TYPE(T) typename T::char_type Chris@16: #define FUSION_GET_TRAITS_TYPE(T) typename T::traits_type Chris@16: Chris@16: #define FUSION_STRING_OF_STREAM(Stream) \ Chris@16: std::basic_string< \ Chris@16: FUSION_GET_CHAR_TYPE(Stream) \ Chris@16: , FUSION_GET_TRAITS_TYPE(Stream) \ Chris@16: > Chris@16: Chris@16: //$$$ these should be part of the public API$$$ Chris@16: //$$$ rename tuple_open, tuple_close and tuple_delimiter to Chris@16: // open, close and delimeter and add these synonyms to the Chris@16: // TR1 tuple module. Chris@16: Chris@16: namespace boost { namespace fusion Chris@16: { Chris@16: namespace detail Chris@16: { Chris@16: template Chris@16: int get_xalloc_index(Tag* = 0) Chris@16: { Chris@16: // each Tag will have a unique index Chris@16: static int index = std::ios::xalloc(); Chris@16: return index; Chris@16: } Chris@16: Chris@16: template Chris@16: struct stream_data Chris@16: { Chris@16: struct arena Chris@16: { Chris@16: ~arena() Chris@16: { Chris@16: for ( Chris@16: typename std::vector::iterator i = data.begin() Chris@16: ; i != data.end() Chris@16: ; ++i) Chris@16: { Chris@16: delete *i; Chris@16: } Chris@16: } Chris@16: Chris@16: std::vector data; Chris@16: }; Chris@16: Chris@16: static void attach(Stream& stream, T const& data) Chris@16: { Chris@16: static arena ar; // our arena Chris@16: ar.data.push_back(new T(data)); Chris@16: stream.pword(get_xalloc_index()) = ar.data.back(); Chris@16: } Chris@16: Chris@16: static T const* get(Stream& stream) Chris@16: { Chris@16: return (T const*)stream.pword(get_xalloc_index()); Chris@16: } Chris@16: }; Chris@16: Chris@16: template Chris@16: class string_ios_manip Chris@16: { Chris@16: public: Chris@16: Chris@16: typedef FUSION_STRING_OF_STREAM(Stream) string_type; Chris@16: Chris@16: typedef stream_data stream_data_t; Chris@16: Chris@16: string_ios_manip(Stream& str_) Chris@16: : stream(str_) Chris@16: {} Chris@16: Chris@16: void Chris@16: set(string_type const& s) Chris@16: { Chris@16: stream_data_t::attach(stream, s); Chris@16: } Chris@16: Chris@16: void Chris@16: print(char const* default_) const Chris@16: { Chris@16: // print a delimiter Chris@16: string_type const* p = stream_data_t::get(stream); Chris@16: if (p) Chris@16: stream << *p; Chris@16: else Chris@16: stream << default_; Chris@16: } Chris@16: Chris@16: void Chris@16: read(char const* default_) const Chris@16: { Chris@16: // read a delimiter Chris@16: string_type const* p = stream_data_t::get(stream); Chris@16: using namespace std; Chris@16: ws(stream); Chris@16: Chris@16: if (p) Chris@16: { Chris@16: typedef typename string_type::const_iterator iterator; Chris@16: for (iterator i = p->begin(); i != p->end(); ++i) Chris@16: check_delim(*i); Chris@16: } Chris@16: else Chris@16: { Chris@16: while (*default_) Chris@16: check_delim(*default_++); Chris@16: } Chris@16: } Chris@16: Chris@16: private: Chris@16: Chris@16: template Chris@16: void Chris@16: check_delim(Char c) const Chris@16: { Chris@16: if (!isspace(c)) Chris@16: { Chris@16: if (stream.get() != c) Chris@16: { Chris@16: stream.unget(); Chris@16: stream.setstate(std::ios::failbit); Chris@16: } Chris@16: } Chris@16: } Chris@16: Chris@16: Stream& stream; Chris@16: Chris@16: private: Chris@16: // silence MSVC warning C4512: assignment operator could not be generated Chris@16: string_ios_manip& operator= (string_ios_manip const&); Chris@16: }; Chris@16: Chris@16: } // detail Chris@16: Chris@16: Chris@16: #if defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) Chris@16: Chris@16: #define STD_TUPLE_DEFINE_MANIPULATOR_FUNCTIONS(name) \ Chris@16: template \ Chris@16: inline detail::name##_type \ Chris@16: name(const std::basic_string& s) \ Chris@16: { \ Chris@16: return detail::name##_type(s); \ Chris@16: } \ Chris@16: \ Chris@16: inline detail::name##_type \ Chris@16: name(char const* s) \ Chris@16: { \ Chris@16: return detail::name##_type(std::basic_string(s)); \ Chris@16: } \ Chris@16: \ Chris@16: inline detail::name##_type \ Chris@16: name(wchar_t const* s) \ Chris@16: { \ Chris@16: return detail::name##_type(std::basic_string(s)); \ Chris@16: } \ Chris@16: \ Chris@16: inline detail::name##_type \ Chris@16: name(char c) \ Chris@16: { \ Chris@16: return detail::name##_type(std::basic_string(1, c)); \ Chris@16: } \ Chris@16: \ Chris@16: inline detail::name##_type \ Chris@16: name(wchar_t c) \ Chris@16: { \ Chris@16: return detail::name##_type(std::basic_string(1, c)); \ Chris@16: } Chris@16: Chris@16: #else // defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) Chris@16: Chris@16: #define STD_TUPLE_DEFINE_MANIPULATOR_FUNCTIONS(name) \ Chris@16: template \ Chris@16: inline detail::name##_type \ Chris@16: name(const std::basic_string& s) \ Chris@16: { \ Chris@16: return detail::name##_type(s); \ Chris@16: } \ Chris@16: \ Chris@16: template \ Chris@16: inline detail::name##_type \ Chris@16: name(Char s[]) \ Chris@16: { \ Chris@16: return detail::name##_type(std::basic_string(s)); \ Chris@16: } \ Chris@16: \ Chris@16: template \ Chris@16: inline detail::name##_type \ Chris@16: name(Char const s[]) \ Chris@16: { \ Chris@16: return detail::name##_type(std::basic_string(s)); \ Chris@16: } \ Chris@16: \ Chris@16: template \ Chris@16: inline detail::name##_type \ Chris@16: name(Char c) \ Chris@16: { \ Chris@16: return detail::name##_type(std::basic_string(1, c)); \ Chris@16: } Chris@16: Chris@16: #endif Chris@16: Chris@16: #define STD_TUPLE_DEFINE_MANIPULATOR(name) \ Chris@16: namespace detail \ Chris@16: { \ Chris@16: struct name##_tag; \ Chris@16: \ Chris@16: template > \ Chris@16: struct name##_type \ Chris@16: { \ Chris@16: typedef std::basic_string string_type; \ Chris@16: string_type data; \ Chris@16: name##_type(const string_type& d): data(d) {} \ Chris@16: }; \ Chris@16: \ Chris@16: template \ Chris@16: Stream& operator>>(Stream& s, const name##_type& m) \ Chris@16: { \ Chris@101: string_ios_manip manip(s); \ Chris@101: manip.set(m.data); \ Chris@16: return s; \ Chris@16: } \ Chris@16: \ Chris@16: template \ Chris@16: Stream& operator<<(Stream& s, const name##_type& m) \ Chris@16: { \ Chris@101: string_ios_manip manip(s); \ Chris@101: manip.set(m.data); \ Chris@16: return s; \ Chris@16: } \ Chris@16: } \ Chris@16: Chris@16: Chris@16: STD_TUPLE_DEFINE_MANIPULATOR(tuple_open) Chris@16: STD_TUPLE_DEFINE_MANIPULATOR(tuple_close) Chris@16: STD_TUPLE_DEFINE_MANIPULATOR(tuple_delimiter) Chris@16: Chris@16: STD_TUPLE_DEFINE_MANIPULATOR_FUNCTIONS(tuple_open) Chris@16: STD_TUPLE_DEFINE_MANIPULATOR_FUNCTIONS(tuple_close) Chris@16: STD_TUPLE_DEFINE_MANIPULATOR_FUNCTIONS(tuple_delimiter) Chris@16: Chris@16: #undef STD_TUPLE_DEFINE_MANIPULATOR Chris@16: #undef STD_TUPLE_DEFINE_MANIPULATOR_FUNCTIONS Chris@16: #undef FUSION_STRING_OF_STREAM Chris@16: #undef FUSION_GET_CHAR_TYPE Chris@16: #undef FUSION_GET_TRAITS_TYPE Chris@16: Chris@16: }} Chris@16: Chris@16: #endif