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
							 |