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