forked from boostorg/fusion
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. }
270 lines
12 KiB
C++
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
|