1 /*============================================================================= 2 Copyright (c) 2001-2011 Hartmut Kaiser 3 4 Distributed under the Boost Software License, Version 1.0. (See accompanying 5 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 6 ==============================================================================*/ 7 #if !defined(BOOST_SPIRIT_STREAM_MAY_05_2007_1228PM) 8 #define BOOST_SPIRIT_STREAM_MAY_05_2007_1228PM 9 10 #if defined(_MSC_VER) 11 #pragma once 12 #endif 13 14 #include <boost/spirit/home/qi/detail/string_parse.hpp> 15 #include <boost/spirit/home/qi/stream/detail/match_manip.hpp> 16 #include <boost/spirit/home/qi/stream/detail/iterator_source.hpp> 17 #include <boost/spirit/home/support/detail/hold_any.hpp> 18 19 #include <iosfwd> 20 #include <sstream> 21 22 /////////////////////////////////////////////////////////////////////////////// 23 namespace boost { namespace spirit 24 { 25 /////////////////////////////////////////////////////////////////////////// 26 // Enablers 27 /////////////////////////////////////////////////////////////////////////// 28 template <> 29 struct use_terminal<qi::domain, tag::stream> // enables stream 30 : mpl::true_ {}; 31 32 template <> 33 struct use_terminal<qi::domain, tag::wstream> // enables wstream 34 : mpl::true_ {}; 35 }} 36 37 /////////////////////////////////////////////////////////////////////////////// 38 namespace boost { namespace spirit { namespace qi 39 { 40 #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS 41 using spirit::stream; 42 using spirit::wstream; 43 #endif 44 using spirit::stream_type; 45 using spirit::wstream_type; 46 47 template <typename Char = char, typename T = spirit::basic_hold_any<char> > 48 struct stream_parser 49 : primitive_parser<stream_parser<Char, T> > 50 { 51 template <typename Context, typename Iterator> 52 struct attribute 53 { 54 typedef T type; 55 }; 56 57 template <typename Iterator, typename Context 58 , typename Skipper, typename Attribute> parseboost::spirit::qi::stream_parser59 bool parse(Iterator& first, Iterator const& last 60 , Context& /*context*/, Skipper const& skipper 61 , Attribute& attr_) const 62 { 63 typedef qi::detail::iterator_source<Iterator> source_device; 64 typedef boost::iostreams::stream<source_device> instream; 65 66 qi::skip_over(first, last, skipper); 67 68 instream in(first, last); // copies 'first' 69 in >> attr_; // use existing operator>>() 70 71 // advance the iterator if everything is ok 72 if (in) { 73 if (!in.eof()) { 74 std::streamsize pos = in.tellg(); 75 std::advance(first, pos); 76 } else { 77 first = last; 78 } 79 return true; 80 } 81 82 return false; 83 } 84 85 template <typename Context> whatboost::spirit::qi::stream_parser86 info what(Context& /*context*/) const 87 { 88 return info("stream"); 89 } 90 }; 91 92 template <typename T, typename Char = char> 93 struct typed_stream 94 : proto::terminal<stream_parser<Char, T> >::type 95 { 96 }; 97 98 /////////////////////////////////////////////////////////////////////////// 99 // Parser generators: make_xxx function (objects) 100 /////////////////////////////////////////////////////////////////////////// 101 template <typename Char> 102 struct make_stream 103 { 104 typedef stream_parser<Char> result_type; operator ()boost::spirit::qi::make_stream105 result_type operator()(unused_type, unused_type) const 106 { 107 return result_type(); 108 } 109 }; 110 111 template <typename Modifiers> 112 struct make_primitive<tag::stream, Modifiers> : make_stream<char> {}; 113 114 template <typename Modifiers> 115 struct make_primitive<tag::wstream, Modifiers> : make_stream<wchar_t> {}; 116 }}} 117 118 #endif 119