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/support/detail/hold_any.hpp> 17 #include <boost/proto/traits.hpp> 18 #include <istream> 19 20 /////////////////////////////////////////////////////////////////////////////// 21 namespace boost { namespace spirit 22 { 23 /////////////////////////////////////////////////////////////////////////// 24 // Enablers 25 /////////////////////////////////////////////////////////////////////////// 26 template <> 27 struct use_terminal<qi::domain, tag::stream> // enables stream 28 : mpl::true_ {}; 29 30 template <> 31 struct use_terminal<qi::domain, tag::wstream> // enables wstream 32 : mpl::true_ {}; 33 }} 34 35 /////////////////////////////////////////////////////////////////////////////// 36 namespace boost { namespace spirit { namespace qi 37 { 38 #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS 39 using spirit::stream; 40 using spirit::wstream; 41 #endif 42 using spirit::stream_type; 43 using spirit::wstream_type; 44 45 namespace detail 46 { 47 template <typename Iterator> 48 struct psbuf 49 : std::basic_streambuf<typename std::iterator_traits<Iterator>::value_type> 50 { psbufboost::spirit::qi::detail::psbuf51 psbuf(Iterator first_, Iterator const& last_) 52 : first(first_), last(last_) {} 53 54 // silence MSVC warning C4512: assignment operator could not be generated 55 BOOST_DELETED_FUNCTION(psbuf& operator=(psbuf const&)) 56 57 protected: underflowboost::spirit::qi::detail::psbuf58 typename psbuf::int_type underflow() BOOST_OVERRIDE 59 { 60 return first == last ? psbuf::traits_type::eof() 61 : psbuf::traits_type::to_int_type(*first); 62 } 63 uflowboost::spirit::qi::detail::psbuf64 typename psbuf::int_type uflow() BOOST_OVERRIDE 65 { 66 return first == last ? psbuf::traits_type::eof() 67 : psbuf::traits_type::to_int_type(*first++); 68 } 69 70 public: 71 Iterator first; 72 Iterator const& last; 73 }; 74 } 75 76 template <typename Char = char, typename T = spirit::basic_hold_any<char> > 77 struct stream_parser 78 : primitive_parser<stream_parser<Char, T> > 79 { 80 template <typename Context, typename Iterator> 81 struct attribute 82 { 83 typedef T type; 84 }; 85 86 template <typename Iterator, typename Context 87 , typename Skipper, typename Attribute> parseboost::spirit::qi::stream_parser88 bool parse(Iterator& first, Iterator const& last 89 , Context& /*context*/, Skipper const& skipper 90 , Attribute& attr_) const 91 { 92 qi::skip_over(first, last, skipper); 93 94 detail::psbuf<Iterator> pseudobuf(first, last); 95 std::basic_istream<Char> in(&pseudobuf); 96 in >> attr_; // use existing operator>>() 97 98 // advance the iterator if everything is ok 99 if (in) { 100 first = pseudobuf.first; 101 return true; 102 } 103 104 return false; 105 } 106 107 template <typename Context> whatboost::spirit::qi::stream_parser108 info what(Context& /*context*/) const 109 { 110 return info("stream"); 111 } 112 }; 113 114 template <typename T, typename Char = char> 115 struct typed_stream 116 : proto::terminal<stream_parser<Char, T> >::type 117 { 118 }; 119 120 /////////////////////////////////////////////////////////////////////////// 121 // Parser generators: make_xxx function (objects) 122 /////////////////////////////////////////////////////////////////////////// 123 template <typename Char> 124 struct make_stream 125 { 126 typedef stream_parser<Char> result_type; operator ()boost::spirit::qi::make_stream127 result_type operator()(unused_type, unused_type) const 128 { 129 return result_type(); 130 } 131 }; 132 133 template <typename Modifiers> 134 struct make_primitive<tag::stream, Modifiers> : make_stream<char> {}; 135 136 template <typename Modifiers> 137 struct make_primitive<tag::wstream, Modifiers> : make_stream<wchar_t> {}; 138 }}} 139 140 #endif 141