Files
boost_fusion/include/boost/fusion/sequence/io/detail/manip.hpp
Kohei Takahashi 687668c110 Fix sprious compile error on VS2015 Preview.
MSVC 2015 Preview will treat unary-ctor call as a variable declaration
even if member call follows, which member has the same name with any
other class (i.e. there are no relations between the member and such
class). This issue already reported at [1].

1. https://connect.microsoft.com/VisualStudio/feedback/details/1037783/unary-ctor-call-v-s-variable-decl

    struct foo
    {
        foo(int) {}
        void set() {}
    };

    struct set;

    int main()
    {
        int i;
        foo(i).set(); // VS2015 try to decl `i` here and conflict with above.
    }
2014-11-24 03:07:16 +09:00

270 lines
12 KiB
C++

/*=============================================================================
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);
using namespace 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