123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268 |
- /*=============================================================================
- 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
- {
- using namespace std;
- if (!isspace(c))
- {
- if (stream.get() != c)
- {
- stream.unget();
- stream.setstate(std::ios::failbit);
- }
- }
- }
- Stream& stream;
- // silence MSVC warning C4512: assignment operator could not be generated
- BOOST_DELETED_FUNCTION(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
|