Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-19 09:47:39

0001 //  Copyright (c) 2001-2011 Hartmut Kaiser
0002 //
0003 //  Distributed under the Boost Software License, Version 1.0. (See accompanying
0004 //  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0005 
0006 #if !defined(BOOST_SPIRIT_KARMA_SYMBOLS_NOV_23_2009_1251PM)
0007 #define BOOST_SPIRIT_KARMA_SYMBOLS_NOV_23_2009_1251PM
0008 
0009 #include <boost/spirit/home/support/common_terminals.hpp>
0010 #include <boost/spirit/home/support/info.hpp>
0011 #include <boost/spirit/home/support/unused.hpp>
0012 #include <boost/spirit/home/support/attributes_fwd.hpp>
0013 #include <boost/spirit/home/support/detail/get_encoding.hpp>
0014 #include <boost/spirit/home/karma/detail/attributes.hpp>
0015 #include <boost/spirit/home/karma/detail/extract_from.hpp>
0016 #include <boost/spirit/home/karma/domain.hpp>
0017 #include <boost/spirit/home/karma/meta_compiler.hpp>
0018 #include <boost/spirit/home/karma/reference.hpp>
0019 #include <boost/spirit/home/karma/generate.hpp>
0020 #include <boost/spirit/home/karma/delimit_out.hpp>
0021 #include <boost/spirit/home/karma/detail/get_casetag.hpp>
0022 #include <boost/spirit/home/karma/detail/string_generate.hpp>
0023 #include <boost/config.hpp>
0024 #include <boost/proto/extends.hpp>
0025 #include <boost/proto/traits.hpp>
0026 #include <boost/shared_ptr.hpp>
0027 #include <boost/mpl/if.hpp>
0028 #include <map>
0029 #include <set>
0030 
0031 #if defined(BOOST_MSVC)
0032 # pragma warning(push)
0033 # pragma warning(disable: 4355) // 'this' : used in base member initializer list warning
0034 #endif
0035 
0036 ///////////////////////////////////////////////////////////////////////////////
0037 namespace boost { namespace spirit { namespace traits
0038 {
0039     template <typename T, typename Attribute, typename Enable>
0040     struct symbols_lookup
0041     {
0042         typedef
0043             mpl::eval_if<fusion::traits::is_sequence<T>
0044               , traits::detail::value_at_c<T, 0>
0045               , detail::add_const_ref<T> > sequence_type;
0046         typedef typename
0047             mpl::eval_if<traits::is_container<T>
0048               , traits::container_value<T>
0049               , sequence_type>::type type;
0050 
0051         // fusion sequence
0052         template <typename T_>
0053         static type call(T_ const& t, mpl::false_, mpl::true_)
0054         {
0055             return fusion::at_c<0>(t);
0056         }
0057 
0058         // container
0059         template <typename T_, typename IsSequence>
0060         static type call(T_ const& t, mpl::true_, IsSequence)
0061         {
0062             return t[0];
0063         }
0064 
0065         // not a container and not a fusion sequence
0066         template <typename T_>
0067         static type call(T_ const& t, mpl::false_, mpl::false_)
0068         {
0069             return t;
0070         }
0071 
0072         static type call(T const& t)
0073         {
0074             typedef typename traits::is_container<T>::type is_container;
0075             typedef typename fusion::traits::is_sequence<T>::type is_sequence;
0076 
0077             return call(t, is_container(), is_sequence());
0078         }
0079     };
0080 
0081     template <typename Attribute>
0082     struct symbols_lookup<Attribute, Attribute>
0083     {
0084         typedef Attribute const& type;
0085 
0086         static type call(Attribute const& t)
0087         {
0088             return t;
0089         }
0090     };
0091 
0092     template <typename Attribute, typename T, typename Enable>
0093     struct symbols_value
0094     {
0095         typedef
0096             mpl::eval_if<fusion::traits::is_sequence<T>
0097               , traits::detail::value_at_c<T, 1>
0098               , mpl::identity<unused_type> > sequence_type;
0099         typedef typename
0100             mpl::eval_if<traits::is_container<T>
0101               , traits::container_value<T>
0102               , sequence_type>::type type;
0103 
0104         // fusion sequence
0105         template <typename T_>
0106         static type call(T_ const& t, mpl::false_, mpl::true_)
0107         {
0108             return fusion::at_c<1>(t);
0109         }
0110 
0111         // container
0112         template <typename T_, typename IsSequence>
0113         static type call(T_ const& t, mpl::true_, IsSequence)
0114         {
0115             return t[1];
0116         }
0117 
0118         // not a container nor a fusion sequence
0119         template <typename T_>
0120         static type call(T_ const&, mpl::false_, mpl::false_)
0121         {
0122             return unused;
0123         }
0124 
0125         static type call(T const& t)
0126         {
0127             typedef typename traits::is_container<T>::type is_container;
0128             typedef typename fusion::traits::is_sequence<T>::type is_sequence;
0129 
0130             return call(t, is_container(), is_sequence());
0131         }
0132     };
0133 
0134     template <typename Attribute>
0135     struct symbols_value<Attribute, Attribute>
0136     {
0137         typedef unused_type type;
0138 
0139         static type call(Attribute const&)
0140         {
0141             return unused;
0142         }
0143     };
0144 }}}
0145 
0146 ///////////////////////////////////////////////////////////////////////////////
0147 namespace boost { namespace spirit { namespace karma
0148 {
0149     ///////////////////////////////////////////////////////////////////////////
0150     template <typename T, typename Attribute>
0151     struct symbols_lookup
0152       : mpl::if_<
0153             traits::not_is_unused<T>
0154           , std::map<Attribute, T>
0155           , std::set<Attribute>
0156         >
0157     {};
0158 
0159     ///////////////////////////////////////////////////////////////////////////
0160     namespace detail
0161     {
0162         ///////////////////////////////////////////////////////////////////////
0163         template <typename CharEncoding, typename Tag>
0164         struct generate_encoded
0165         {
0166             typedef typename
0167                 proto::terminal<tag::char_code<Tag, CharEncoding> >::type
0168             encoding_type;
0169 
0170             template <typename OutputIterator, typename Expr, typename Attribute>
0171             static bool call(OutputIterator& sink, Expr const& expr
0172               , Attribute const& attr)
0173             {
0174                 encoding_type const encoding = encoding_type();
0175                 return karma::generate(sink, encoding[expr], attr);
0176             }
0177         };
0178 
0179         template <>
0180         struct generate_encoded<unused_type, unused_type>
0181         {
0182             template <typename OutputIterator, typename Expr, typename Attribute>
0183             static bool call(OutputIterator& sink, Expr const& expr
0184               , Attribute const& attr)
0185             {
0186                 return karma::generate(sink, expr, attr);
0187             }
0188         };
0189     }
0190 
0191     template <
0192         typename Attribute = char, typename T = unused_type
0193       , typename Lookup = typename symbols_lookup<T, Attribute>::type
0194       , typename CharEncoding = unused_type, typename Tag = unused_type>
0195     struct symbols
0196       : proto::extends<
0197             typename proto::terminal<
0198                 reference<symbols<Attribute, T, Lookup, CharEncoding, Tag> >
0199             >::type
0200           , symbols<Attribute, T, Lookup, CharEncoding, Tag> >
0201       , primitive_generator<
0202             symbols<Attribute, T, Lookup, CharEncoding, Tag> >
0203     {
0204         typedef T value_type;       // the value associated with each entry
0205 
0206         typedef reference<symbols> reference_;
0207         typedef typename proto::terminal<reference_>::type terminal;
0208         typedef proto::extends<terminal, symbols> base_type;
0209 
0210         template <typename Context, typename Unused>
0211         struct attribute
0212         {
0213             typedef Attribute type;
0214         };
0215 
0216         symbols(std::string const& name = "symbols")
0217           : base_type(terminal::make(reference_(*this)))
0218           , add(*this)
0219           , remove(*this)
0220           , lookup(new Lookup())
0221           , name_(name)
0222         {}
0223 
0224         symbols(symbols const& syms)
0225           : base_type(terminal::make(reference_(*this)))
0226           , add(*this)
0227           , remove(*this)
0228           , lookup(syms.lookup)
0229           , name_(syms.name_)
0230         {}
0231 
0232         template <typename CharEncoding_, typename Tag_>
0233         symbols(symbols<Attribute, T, Lookup, CharEncoding_, Tag_> const& syms)
0234           : base_type(terminal::make(reference_(*this)))
0235           , add(*this)
0236           , remove(*this)
0237           , lookup(syms.lookup)
0238           , name_(syms.name_)
0239         {}
0240 
0241         template <typename Symbols, typename Data>
0242         symbols(Symbols const& syms, Data const& data
0243               , std::string const& name = "symbols")
0244           : base_type(terminal::make(reference_(*this)))
0245           , add(*this)
0246           , remove(*this)
0247           , lookup(new Lookup())
0248           , name_(name)
0249         {
0250             typename range_const_iterator<Symbols>::type si = boost::begin(syms);
0251             typename range_const_iterator<Data>::type di = boost::begin(data);
0252             while (si != boost::end(syms))
0253                 add(*si++, *di++);
0254         }
0255 
0256         symbols&
0257         operator=(symbols const& rhs)
0258         {
0259             *lookup = *rhs.lookup;
0260             name_ = rhs.name_;
0261             return *this;
0262         }
0263 
0264         template <typename CharEncoding_, typename Tag_>
0265         symbols&
0266         operator=(symbols<Attribute, T, Lookup, CharEncoding_, Tag_> const& rhs)
0267         {
0268             *lookup = *rhs.lookup;
0269             name_ = rhs.name_;
0270             return *this;
0271         }
0272 
0273         void clear()
0274         {
0275             lookup->clear();
0276         }
0277 
0278         struct adder;
0279         struct remover;
0280 
0281         template <typename Attr, typename T_>
0282         adder const&
0283         operator=(std::pair<Attr, T_> const& p)
0284         {
0285             lookup->clear();
0286             return add(p.first, p.second);
0287         }
0288 
0289         template <typename Attr, typename T_>
0290         friend adder const&
0291         operator+= (symbols& sym, std::pair<Attr, T_> const& p)
0292         {
0293             return sym.add(p.first, p.second);
0294         }
0295 
0296         template <typename Attr>
0297         friend remover const&
0298         operator-= (symbols& sym, Attr const& attr)
0299         {
0300             return sym.remove(attr);
0301         }
0302 
0303 #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
0304         // non-const version needed to suppress proto's += kicking in
0305         template <typename Attr, typename T_>
0306         friend adder const&
0307         operator+= (symbols& sym, std::pair<Attr, T_>& p)
0308         {
0309             return sym.add(p.first, p.second);
0310         }
0311 
0312         // non-const version needed to suppress proto's -= kicking in
0313         template <typename Attr>
0314         friend remover const&
0315         operator-= (symbols& sym, Attr& attr)
0316         {
0317             return sym.remove(attr);
0318         }
0319 #else
0320         // for rvalue references
0321         template <typename Attr, typename T_>
0322         friend adder const&
0323         operator+= (symbols& sym, std::pair<Attr, T_>&& p)
0324         {
0325             return sym.add(p.first, p.second);
0326         }
0327 
0328         // for rvalue references
0329         template <typename Attr>
0330         friend remover const&
0331         operator-= (symbols& sym, Attr&& attr)
0332         {
0333             return sym.remove(attr);
0334         }
0335 #endif
0336         template <typename F>
0337         void for_each(F f) const
0338         {
0339             std::for_each(lookup->begin(), lookup->end(), f);
0340         }
0341 
0342         template <typename Attr>
0343         value_type* find(Attr const& attr)
0344         {
0345             typename Lookup::iterator it = lookup->find(attr);
0346             return (it != lookup->end()) ? &(*it).second : 0;
0347         }
0348 
0349         template <typename Attr>
0350         value_type& at(Attr const& attr)
0351         {
0352             return (*lookup)[attr];
0353         }
0354 
0355         ///////////////////////////////////////////////////////////////////////
0356         template <typename OutputIterator, typename Context, typename Delimiter
0357           , typename Attr>
0358         bool generate(OutputIterator& sink, Context&, Delimiter const& d
0359           , Attr const& attr) const
0360         {
0361             typename Lookup::iterator it = lookup->find(
0362                 traits::symbols_lookup<Attr, Attribute>::call(attr));
0363             if (it == lookup->end())
0364                 return false;
0365 
0366             return karma::detail::generate_encoded<CharEncoding, Tag>::call(
0367                         sink, (*it).second
0368                       , traits::symbols_value<Attribute, Attr>::call(attr)) &&
0369                    karma::delimit_out(sink, d);
0370         }
0371 
0372         template <typename Context>
0373         info what(Context&) const
0374         {
0375             return info(name_);
0376         }
0377 
0378         void name(std::string const &str)
0379         {
0380             name_ = str;
0381         }
0382         std::string const &name() const
0383         {
0384             return name_;
0385         }
0386 
0387         ///////////////////////////////////////////////////////////////////////
0388 #ifdef _MSC_VER
0389 #  pragma warning(push)
0390 #  pragma warning(disable: 4512) // assignment operator could not be generated.
0391 #endif
0392         struct adder
0393         {
0394             template <typename, typename = unused_type>
0395             struct result { typedef adder const& type; };
0396 
0397             adder(symbols& sym)
0398               : sym(sym)
0399             {
0400             }
0401 
0402             template <typename Attr>
0403             adder const&
0404             operator()(Attr const& attr, T const& val = T()) const
0405             {
0406                 sym.lookup->insert(typename Lookup::value_type(attr, val));
0407                 return *this;
0408             }
0409 
0410             template <typename Attr>
0411             adder const&
0412             operator, (Attr const& attr) const
0413             {
0414                 sym.lookup->insert(typename Lookup::value_type(attr, T()));
0415                 return *this;
0416             }
0417 
0418             symbols& sym;
0419         };
0420 
0421         struct remover
0422         {
0423             template <typename>
0424             struct result { typedef remover const& type; };
0425 
0426             remover(symbols& sym)
0427               : sym(sym)
0428             {
0429             }
0430 
0431             template <typename Attr>
0432             remover const&
0433             operator()(Attr const& attr) const
0434             {
0435                 sym.lookup->erase(attr);
0436                 return *this;
0437             }
0438 
0439             template <typename Attr>
0440             remover const&
0441             operator, (Attr const& attr) const
0442             {
0443                 sym.lookup->erase(attr);
0444                 return *this;
0445             }
0446 
0447             symbols& sym;
0448         };
0449 #ifdef _MSC_VER
0450 #  pragma warning(pop)
0451 #endif
0452 
0453         adder add;
0454         remover remove;
0455         shared_ptr<Lookup> lookup;
0456         std::string name_;
0457     };
0458 
0459     ///////////////////////////////////////////////////////////////////////////
0460     // specialization for unused stored type
0461     template <
0462         typename Attribute, typename Lookup
0463       , typename CharEncoding, typename Tag>
0464     struct symbols<Attribute, unused_type, Lookup, CharEncoding, Tag>
0465       : proto::extends<
0466             typename proto::terminal<
0467                 spirit::karma::reference<
0468                     symbols<Attribute, unused_type, Lookup, CharEncoding, Tag> >
0469             >::type
0470           , symbols<Attribute, unused_type, Lookup, CharEncoding, Tag>
0471         >
0472       , spirit::karma::generator<
0473             symbols<Attribute, unused_type, Lookup, CharEncoding, Tag> >
0474     {
0475         typedef unused_type value_type;  // the value associated with each entry
0476 
0477         typedef spirit::karma::reference<symbols> reference_;
0478         typedef typename proto::terminal<reference_>::type terminal;
0479         typedef proto::extends<terminal, symbols> base_type;
0480 
0481         template <typename Context, typename Unused>
0482         struct attribute
0483         {
0484             typedef Attribute type;
0485         };
0486 
0487         symbols(std::string const& name = "symbols")
0488           : base_type(terminal::make(reference_(*this)))
0489           , add(*this)
0490           , remove(*this)
0491           , lookup(new Lookup())
0492           , name_(name)
0493         {}
0494 
0495         symbols(symbols const& syms)
0496           : base_type(terminal::make(reference_(*this)))
0497           , add(*this)
0498           , remove(*this)
0499           , lookup(syms.lookup)
0500           , name_(syms.name_)
0501         {}
0502 
0503         template <typename CharEncoding_, typename Tag_>
0504         symbols(symbols<Attribute, unused_type, Lookup, CharEncoding_, Tag_> const& syms)
0505           : base_type(terminal::make(reference_(*this)))
0506           , add(*this)
0507           , remove(*this)
0508           , lookup(syms.lookup)
0509           , name_(syms.name_)
0510         {}
0511 
0512         template <typename Symbols, typename Data>
0513         symbols(Symbols const& syms, Data const& data
0514               , std::string const& name = "symbols")
0515           : base_type(terminal::make(reference_(*this)))
0516           , add(*this)
0517           , remove(*this)
0518           , lookup(new Lookup())
0519           , name_(name)
0520         {
0521             typename range_const_iterator<Symbols>::type si = boost::begin(syms);
0522             typename range_const_iterator<Data>::type di = boost::begin(data);
0523             while (si != boost::end(syms))
0524                 add(*si++, *di++);
0525         }
0526 
0527         symbols&
0528         operator=(symbols const& rhs)
0529         {
0530             *lookup = *rhs.lookup;
0531             name_ = rhs.name_;
0532             return *this;
0533         }
0534 
0535         template <typename CharEncoding_, typename Tag_>
0536         symbols&
0537         operator=(symbols<Attribute, unused_type, Lookup, CharEncoding_, Tag_> const& rhs)
0538         {
0539             *lookup = *rhs.lookup;
0540             name_ = rhs.name_;
0541             return *this;
0542         }
0543 
0544         void clear()
0545         {
0546             lookup->clear();
0547         }
0548 
0549         struct adder;
0550         struct remover;
0551 
0552         template <typename Attr>
0553         adder const&
0554         operator=(Attr const& attr)
0555         {
0556             lookup->clear();
0557             return add(attr);
0558         }
0559 
0560         template <typename Attr>
0561         friend adder const&
0562         operator+= (symbols& sym, Attr const& attr)
0563         {
0564             return sym.add(attr);
0565         }
0566 
0567         template <typename Attr>
0568         friend remover const&
0569         operator-= (symbols& sym, Attr const& attr)
0570         {
0571             return sym.remove(attr);
0572         }
0573 
0574         // non-const version needed to suppress proto's += kicking in
0575         template <typename Attr>
0576         friend adder const&
0577         operator+= (symbols& sym, Attr& attr)
0578         {
0579             return sym.add(attr);
0580         }
0581 
0582         // non-const version needed to suppress proto's -= kicking in
0583         template <typename Attr>
0584         friend remover const&
0585         operator-= (symbols& sym, Attr& attr)
0586         {
0587             return sym.remove(attr);
0588         }
0589 
0590         template <typename F>
0591         void for_each(F f) const
0592         {
0593             std::for_each(lookup->begin(), lookup->end(), f);
0594         }
0595 
0596         template <typename Attr>
0597         value_type const* find(Attr const& attr)
0598         {
0599             typename Lookup::iterator it = lookup->find(attr);
0600             return (it != lookup->end()) ? &unused : 0;
0601         }
0602 
0603         template <typename Attr>
0604         value_type at(Attr const& attr)
0605         {
0606             typename Lookup::iterator it = lookup->find(attr);
0607             if (it == lookup->end())
0608                 add(attr);
0609             return unused;
0610         }
0611 
0612         ///////////////////////////////////////////////////////////////////////
0613         template <typename OutputIterator, typename Context, typename Delimiter
0614           , typename Attr>
0615         bool generate(OutputIterator& sink, Context&, Delimiter const& d
0616           , Attr const& attr) const
0617         {
0618             typename Lookup::iterator it = lookup->find(
0619                 traits::symbols_lookup<Attr, Attribute>::call(attr));
0620             if (it == lookup->end())
0621                 return false;
0622 
0623             return karma::detail::generate_encoded<CharEncoding, Tag>::
0624                       call(sink
0625                         , traits::symbols_lookup<Attr, Attribute>::call(attr)
0626                         , unused) &&
0627                    karma::delimit_out(sink, d);
0628         }
0629 
0630         template <typename Context>
0631         info what(Context&) const
0632         {
0633             return info(name_);
0634         }
0635 
0636         void name(std::string const &str)
0637         {
0638             name_ = str;
0639         }
0640         std::string const &name() const
0641         {
0642             return name_;
0643         }
0644 
0645         ///////////////////////////////////////////////////////////////////////
0646 #ifdef _MSC_VER
0647 #  pragma warning(push)
0648 #  pragma warning(disable: 4512) // assignment operator could not be generated.
0649 #endif
0650         struct adder
0651         {
0652             template <typename, typename = unused_type>
0653             struct result { typedef adder const& type; };
0654 
0655             adder(symbols& sym)
0656               : sym(sym)
0657             {
0658             }
0659 
0660             template <typename Attr>
0661             adder const&
0662             operator()(Attr const& attr) const
0663             {
0664                 sym.lookup->insert(attr);
0665                 return *this;
0666             }
0667 
0668             template <typename Attr>
0669             adder const&
0670             operator, (Attr const& attr) const
0671             {
0672                 sym.lookup->insert(attr);
0673                 return *this;
0674             }
0675 
0676             symbols& sym;
0677         };
0678 
0679         struct remover
0680         {
0681             template <typename>
0682             struct result { typedef remover const& type; };
0683 
0684             remover(symbols& sym)
0685               : sym(sym)
0686             {
0687             }
0688 
0689             template <typename Attr>
0690             remover const&
0691             operator()(Attr const& attr) const
0692             {
0693                 sym.lookup->erase(attr);
0694                 return *this;
0695             }
0696 
0697             template <typename Attr>
0698             remover const&
0699             operator, (Attr const& attr) const
0700             {
0701                 sym.lookup->erase(attr);
0702                 return *this;
0703             }
0704 
0705             symbols& sym;
0706         };
0707 #ifdef _MSC_VER
0708 #  pragma warning(pop)
0709 #endif
0710 
0711         adder add;
0712         remover remove;
0713         shared_ptr<Lookup> lookup;
0714         std::string name_;
0715     };
0716 
0717     ///////////////////////////////////////////////////////////////////////////
0718     // Generator generators: make_xxx function (objects)
0719     ///////////////////////////////////////////////////////////////////////////
0720     template <typename Attribute, typename T, typename Lookup
0721       , typename CharEnconding, typename Tag, typename Modifiers>
0722     struct make_primitive<
0723         reference<symbols<Attribute, T, Lookup, CharEnconding, Tag> >
0724       , Modifiers>
0725     {
0726         static bool const lower =
0727             has_modifier<Modifiers, tag::char_code_base<tag::lower> >::value;
0728         static bool const upper =
0729             has_modifier<Modifiers, tag::char_code_base<tag::upper> >::value;
0730 
0731         typedef reference<
0732             symbols<Attribute, T, Lookup, CharEnconding, Tag>
0733         > reference_;
0734 
0735         typedef typename mpl::if_c<
0736             lower || upper
0737           , symbols<
0738                 Attribute, T, Lookup
0739               , typename spirit::detail::get_encoding_with_case<
0740                     Modifiers, unused_type, lower || upper>::type
0741               , typename detail::get_casetag<Modifiers, lower || upper>::type>
0742           , reference_>::type
0743         result_type;
0744 
0745         result_type operator()(reference_ ref, unused_type) const
0746         {
0747             return result_type(ref.ref.get());
0748         }
0749     };
0750 }}}
0751 
0752 namespace boost { namespace spirit { namespace traits
0753 {
0754     ///////////////////////////////////////////////////////////////////////////
0755     template <typename Attribute, typename T, typename Lookup
0756       , typename CharEncoding, typename Tag
0757       , typename Attr, typename Context, typename Iterator>
0758     struct handles_container<karma::symbols<Attribute, T, Lookup, CharEncoding, Tag>
0759             , Attr, Context, Iterator>
0760       : traits::is_container<Attr> {};
0761 }}}
0762 
0763 #if defined(BOOST_MSVC)
0764 # pragma warning(pop)
0765 #endif
0766 
0767 #endif
0768