text: /*=============================================================================
      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 <qsboost/fusion/support/config.hpp>
  #include <qsboost/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 qsboost { 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(QSBOOST_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
  