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
 | 
