forked from boostorg/fusion
Initial move from Spirit CVS
[SVN r34896]
This commit is contained in:
86
include/boost/fusion/sequence/io/detail/in.hpp
Normal file
86
include/boost/fusion/sequence/io/detail/in.hpp
Normal file
@ -0,0 +1,86 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 1999-2003 Jaakko J<>rvi
|
||||
Copyright (c) 1999-2003 Jeremiah Willcock
|
||||
Copyright (c) 2001-2006 Joel de Guzman
|
||||
|
||||
Use, modification and distribution is subject to 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_IN_05052005_0121)
|
||||
#define FUSION_IN_05052005_0121
|
||||
|
||||
#include <iostream>
|
||||
#include <boost/fusion/sequence/io/detail/manip.hpp>
|
||||
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/fusion/sequence/intrinsic/begin.hpp>
|
||||
#include <boost/fusion/sequence/intrinsic/end.hpp>
|
||||
#include <boost/fusion/iterator/deref.hpp>
|
||||
#include <boost/fusion/iterator/next.hpp>
|
||||
#include <boost/fusion/iterator/equal_to.hpp>
|
||||
|
||||
namespace boost { namespace fusion { namespace detail
|
||||
{
|
||||
template <typename Tag>
|
||||
struct delimiter_in
|
||||
{
|
||||
// read a delimiter
|
||||
template <typename IS>
|
||||
static void
|
||||
read(IS& is, char const* delim, mpl::false_ = mpl::false_())
|
||||
{
|
||||
detail::string_ios_manip<Tag, IS> manip(is);
|
||||
manip.read(delim);
|
||||
}
|
||||
|
||||
template <typename IS>
|
||||
static void
|
||||
read(IS& is, char const* delim, mpl::true_)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct read_sequence_loop
|
||||
{
|
||||
template <typename IS, typename First, typename Last>
|
||||
static void
|
||||
call(IS& is, First const&, Last const&, mpl::true_)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename IS, typename First, typename Last>
|
||||
static void
|
||||
call(IS& is, First const& first, Last const& last, mpl::false_)
|
||||
{
|
||||
result_of::equal_to<
|
||||
typename result_of::next<First>::type
|
||||
, Last
|
||||
>
|
||||
is_last;
|
||||
|
||||
is >> *first;
|
||||
delimiter_in<tuple_delimiter_tag>::read(is, " ", is_last);
|
||||
call(is, fusion::next(first), last, is_last);
|
||||
}
|
||||
|
||||
template <typename IS, typename First, typename Last>
|
||||
static void
|
||||
call(IS& is, First const& first, Last const& last)
|
||||
{
|
||||
result_of::equal_to<First, Last> eq;
|
||||
call(is, first, last, eq);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename IS, typename Sequence>
|
||||
inline void
|
||||
read_sequence(IS& is, Sequence& seq)
|
||||
{
|
||||
delimiter_in<tuple_open_tag>::read(is, "(");
|
||||
read_sequence_loop::call(is, fusion::begin(seq), fusion::end(seq));
|
||||
delimiter_in<tuple_close_tag>::read(is, ")");
|
||||
}
|
||||
}}}
|
||||
|
||||
#endif
|
318
include/boost/fusion/sequence/io/detail/manip.hpp
Normal file
318
include/boost/fusion/sequence/io/detail/manip.hpp
Normal file
@ -0,0 +1,318 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 1999-2003 Jeremiah Willcock
|
||||
Copyright (c) 1999-2003 Jaakko J<>rvi
|
||||
Copyright (c) 2001-2006 Joel de Guzman
|
||||
|
||||
Use, modification and distribution is subject to 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/config.hpp>
|
||||
#include <iostream>
|
||||
#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
|
||||
|
||||
#if defined (BOOST_NO_TEMPLATED_STREAMS)
|
||||
#define FUSION_STRING_OF_STREAM(Stream) std::string
|
||||
#else
|
||||
#define FUSION_STRING_OF_STREAM(Stream) \
|
||||
std::basic_string< \
|
||||
FUSION_GET_CHAR_TYPE(Stream) \
|
||||
, FUSION_GET_TRAITS_TYPE(Stream) \
|
||||
>
|
||||
#endif
|
||||
|
||||
//$$$ 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;
|
||||
};
|
||||
|
||||
} // detail
|
||||
|
||||
#if defined (BOOST_NO_TEMPLATED_STREAMS)
|
||||
|
||||
#define STD_TUPLE_DEFINE_MANIPULATOR(name) \
|
||||
namespace detail \
|
||||
{ \
|
||||
struct name##_tag; \
|
||||
\
|
||||
struct name##_type \
|
||||
{ \
|
||||
typedef std::string string_type; \
|
||||
string_type data; \
|
||||
name##_type(const string_type& d): data(d) {} \
|
||||
}; \
|
||||
\
|
||||
template <typename Stream> \
|
||||
Stream& operator>>(Stream& s, const name##_type& m) \
|
||||
{ \
|
||||
string_ios_manip<name##_tag, Stream>(s).set(m.data); \
|
||||
return s; \
|
||||
} \
|
||||
\
|
||||
template <typename Stream> \
|
||||
Stream& operator<<(Stream& s, const name##_type& m) \
|
||||
{ \
|
||||
string_ios_manip<name##_tag, Stream>(s).set(m.data); \
|
||||
return s; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define STD_TUPLE_DEFINE_MANIPULATOR_FUNCTIONS(name) \
|
||||
inline detail::name##_type \
|
||||
name(const std::string& s) \
|
||||
{ \
|
||||
return detail::name##_type(s); \
|
||||
} \
|
||||
\
|
||||
inline detail::name##_type \
|
||||
name(const char* s) \
|
||||
{ \
|
||||
return detail::name##_type(std::string(s)); \
|
||||
} \
|
||||
\
|
||||
inline detail::name##_type \
|
||||
name(char c) \
|
||||
{ \
|
||||
return detail::name##_type(std::string(1, c)); \
|
||||
}
|
||||
|
||||
#else // defined(BOOST_NO_TEMPLATED_STREAMS)
|
||||
|
||||
#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>(s).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>(s).set(m.data); \
|
||||
return s; \
|
||||
} \
|
||||
} \
|
||||
|
||||
#endif // defined(BOOST_NO_TEMPLATED_STREAMS)
|
||||
|
||||
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
|
86
include/boost/fusion/sequence/io/detail/out.hpp
Normal file
86
include/boost/fusion/sequence/io/detail/out.hpp
Normal file
@ -0,0 +1,86 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 1999-2003 Jaakko J<>rvi
|
||||
Copyright (c) 1999-2003 Jeremiah Willcock
|
||||
Copyright (c) 2001-2006 Joel de Guzman
|
||||
|
||||
Use, modification and distribution is subject to 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_OUT_05052005_0121)
|
||||
#define FUSION_OUT_05052005_0121
|
||||
|
||||
#include <iostream>
|
||||
#include <boost/fusion/sequence/io/detail/manip.hpp>
|
||||
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/fusion/sequence/intrinsic/begin.hpp>
|
||||
#include <boost/fusion/sequence/intrinsic/end.hpp>
|
||||
#include <boost/fusion/iterator/deref.hpp>
|
||||
#include <boost/fusion/iterator/next.hpp>
|
||||
#include <boost/fusion/iterator/equal_to.hpp>
|
||||
|
||||
namespace boost { namespace fusion { namespace detail
|
||||
{
|
||||
template <typename Tag>
|
||||
struct delimiter_out
|
||||
{
|
||||
// print a delimiter
|
||||
template <typename OS>
|
||||
static void
|
||||
print(OS& os, char const* delim, mpl::false_ = mpl::false_())
|
||||
{
|
||||
detail::string_ios_manip<Tag, OS> manip(os);
|
||||
manip.print(delim);
|
||||
}
|
||||
|
||||
template <typename OS>
|
||||
static void
|
||||
print(OS& os, char const* delim, mpl::true_)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct print_sequence_loop
|
||||
{
|
||||
template <typename OS, typename First, typename Last>
|
||||
static void
|
||||
call(OS& os, First const&, Last const&, mpl::true_)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename OS, typename First, typename Last>
|
||||
static void
|
||||
call(OS& os, First const& first, Last const& last, mpl::false_)
|
||||
{
|
||||
result_of::equal_to<
|
||||
typename result_of::next<First>::type
|
||||
, Last
|
||||
>
|
||||
is_last;
|
||||
|
||||
os << *first;
|
||||
delimiter_out<tuple_delimiter_tag>::print(os, " ", is_last);
|
||||
call(os, fusion::next(first), last, is_last);
|
||||
}
|
||||
|
||||
template <typename OS, typename First, typename Last>
|
||||
static void
|
||||
call(OS& os, First const& first, Last const& last)
|
||||
{
|
||||
result_of::equal_to<First, Last> eq;
|
||||
call(os, first, last, eq);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename OS, typename Sequence>
|
||||
inline void
|
||||
print_sequence(OS& os, Sequence const& seq)
|
||||
{
|
||||
delimiter_out<tuple_open_tag>::print(os, "(");
|
||||
print_sequence_loop::call(os, fusion::begin(seq), fusion::end(seq));
|
||||
delimiter_out<tuple_close_tag>::print(os, ")");
|
||||
}
|
||||
}}}
|
||||
|
||||
#endif
|
Reference in New Issue
Block a user