Imported Upstream version 1.72.0
[platform/upstream/boost.git] / boost / spirit / repository / home / qi / directive / kwd.hpp
1 /*=============================================================================
2     Copyright (c) 2001-2011 Joel de Guzman
3     Copyright (c) 2011 Thomas Bernard
4
5     Distributed under the Boost Software License, Version 1.0. (See accompanying
6     file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 =============================================================================*/
8 #if !defined(SPIRIT_KWD_NOVEMBER_14_2008_1148AM)
9 #define SPIRIT_KWD_NOVEMBER_14_2008_1148AM
10
11 #if defined(_MSC_VER)
12 #pragma once
13 #endif
14
15 #include <boost/spirit/home/qi/meta_compiler.hpp>
16 #include <boost/spirit/home/qi/parser.hpp>
17 #include <boost/spirit/home/qi/auxiliary/lazy.hpp>
18 #include <boost/spirit/home/qi/operator/kleene.hpp>
19 #include <boost/spirit/home/qi/string/lit.hpp>
20 #include <boost/spirit/home/support/container.hpp>
21 #include <boost/spirit/home/qi/detail/attributes.hpp>
22 #include <boost/spirit/home/qi/detail/fail_function.hpp>
23 #include <boost/spirit/home/support/info.hpp>
24 #include <boost/spirit/repository/home/support/kwd.hpp>
25 #include <boost/fusion/include/at.hpp>
26 #include <vector>
27
28 #if defined(_MSC_VER)
29 # pragma warning(push)
30 # pragma warning(disable: 4127) // conditional expression is constant
31 #endif
32
33 namespace boost { namespace spirit
34 {
35     ///////////////////////////////////////////////////////////////////////////
36     // Enablers
37     ///////////////////////////////////////////////////////////////////////////
38
39     template < typename T>
40     struct use_directive<qi::domain
41       , terminal_ex<repository::tag::kwd                     // enables kwd(key)[p]
42         , fusion::vector1<T > >
43     > : mpl::true_ {};
44
45     template < typename T>
46     struct use_directive<qi::domain
47       , terminal_ex<repository::tag::ikwd                     // enables ikwd(key)[p]
48         , fusion::vector1<T > >
49     > : mpl::true_ {};
50
51     template < typename T>
52     struct use_directive<qi::domain
53       , terminal_ex<repository::tag::dkwd                     // enables dkwd(key)[p]
54         , fusion::vector1<T > >
55     > : mpl::true_ {};
56
57     template < typename T>
58     struct use_directive<qi::domain
59       , terminal_ex<repository::tag::idkwd                     // enables idkwd(key)[p]
60         , fusion::vector1<T > >
61     > : mpl::true_ {};
62
63
64     template < typename T1, typename T2>
65     struct use_directive<qi::domain
66       , terminal_ex<repository::tag::kwd                     // enables kwd(key,exact)[p]
67         , fusion::vector2< T1, T2 > >
68     > : mpl::true_ {};
69
70     template < typename T1, typename T2>
71     struct use_directive<qi::domain
72       , terminal_ex<repository::tag::ikwd                     // enables ikwd(key,exact)[p]
73         , fusion::vector2< T1, T2 > >
74     > : mpl::true_ {};
75
76     template < typename T1, typename T2>
77     struct use_directive<qi::domain
78       , terminal_ex<repository::tag::dkwd                     // enables dkwd(key,exact)[p]
79         , fusion::vector2< T1, T2 > >
80     > : mpl::true_ {};
81
82     template < typename T1, typename T2>
83     struct use_directive<qi::domain
84       , terminal_ex<repository::tag::idkwd                     // enables idkwd(key,exact)[p]
85         , fusion::vector2< T1, T2 > >
86     > : mpl::true_ {};
87
88    template < typename T1, typename T2>
89     struct use_directive<qi::domain
90       , terminal_ex<repository::tag::kwd                     // enables kwd(min, max)[p]
91         , fusion::vector3< T1, T2, T2 > >
92     > : mpl::true_ {};
93
94     template < typename T1, typename T2>
95     struct use_directive<qi::domain
96       , terminal_ex<repository::tag::ikwd                     // enables ikwd(min, max)[p]
97         , fusion::vector3< T1, T2, T2 > >
98     > : mpl::true_ {};
99
100     template < typename T1, typename T2>
101     struct use_directive<qi::domain
102       , terminal_ex<repository::tag::dkwd                     // enables dkwd(min, max)[p]
103         , fusion::vector3< T1, T2, T2 > >
104     > : mpl::true_ {};
105
106     template < typename T1, typename T2>
107     struct use_directive<qi::domain
108       , terminal_ex<repository::tag::idkwd                     // enables idkwd(min, max)[p]
109         , fusion::vector3< T1, T2, T2 > >
110     > : mpl::true_ {};
111
112    template < typename T1, typename T2>
113     struct use_directive<qi::domain
114       , terminal_ex<repository::tag::kwd                     // enables kwd(min, inf)[p]
115         , fusion::vector3<T1, T2, inf_type > >
116     > : mpl::true_ {};
117
118     template < typename T1, typename T2>
119     struct use_directive<qi::domain
120       , terminal_ex<repository::tag::ikwd                     // enables ikwd(min, inf)[p]
121         , fusion::vector3<T1, T2, inf_type > >
122     > : mpl::true_ {};
123
124    template < typename T1, typename T2>
125     struct use_directive<qi::domain
126       , terminal_ex<repository::tag::dkwd                     // enables dkwd(min, inf)[p]
127         , fusion::vector3<T1, T2, inf_type > >
128     > : mpl::true_ {};
129
130     template < typename T1, typename T2>
131     struct use_directive<qi::domain
132       , terminal_ex<repository::tag::idkwd                     // enables idkwd(min, inf)[p]
133         , fusion::vector3<T1, T2, inf_type > >
134     > : mpl::true_ {};
135
136
137   /*  template <>                                     // enables *lazy* kwd(exact)[p]
138     struct use_lazy_directive<
139         qi::domain
140       , tag::kwd
141       , 1 // arity
142     > : mpl::true_ {};
143
144     template <>                                     // enables *lazy* kwd(min, max)[p]
145     struct use_lazy_directive<                      // and kwd(min, inf)[p]
146         qi::domain
147       , tag::kwd
148       , 2 // arity
149     > : mpl::true_ {};
150 */
151
152 }}
153
154 namespace boost { namespace spirit { namespace repository { namespace qi
155 {
156 #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
157     using repository::kwd;
158     using repository::ikwd;
159     using repository::dkwd;
160     using repository::idkwd;
161     using spirit::inf;
162 #endif
163     using repository::kwd_type;
164     using repository::ikwd_type;
165     using repository::dkwd_type;
166     using repository::idkwd_type;
167     using spirit::inf_type;
168
169 template <typename T>
170     struct kwd_pass_iterator // handles kwd(exact)[p]
171     {
172         kwd_pass_iterator() {}
173         bool flag_init() const { return true; }
174         bool register_successful_parse(bool &flag,T &/*i*/) const {
175             flag=true;
176             return true;
177         }
178
179
180         // silence MSVC warning C4512: assignment operator could not be generated
181         BOOST_DELETED_FUNCTION(kwd_pass_iterator& operator= (kwd_pass_iterator const&))
182     };
183
184     template <typename T>
185     struct kwd_exact_iterator // handles kwd(exact)[p]
186     {
187         kwd_exact_iterator(T const exact)
188           : exact(exact){}
189
190         typedef T type;
191         bool flag_init() const { return false; }
192         bool register_successful_parse(bool &flag,T &i) const {
193             i++;
194             if(i<exact)
195             {
196                 flag=false;
197                 return true;
198             }
199             else if(i==exact)
200             {
201                 flag=true;
202                 return true;
203             }
204             else
205                 return flag=false;
206
207         }
208         T const exact;
209
210         // silence MSVC warning C4512: assignment operator could not be generated
211         BOOST_DELETED_FUNCTION(kwd_exact_iterator& operator= (kwd_exact_iterator const&))
212     };
213
214     template <typename T>
215     struct kwd_finite_iterator // handles kwd(min, max)[p]
216     {
217         kwd_finite_iterator(T const min, T const max)
218           : min BOOST_PREVENT_MACRO_SUBSTITUTION (min)
219           , max BOOST_PREVENT_MACRO_SUBSTITUTION (max)
220             {}
221
222         typedef T type;
223         bool flag_init() const { return min==0; }
224         bool register_successful_parse(bool &flag,T &i) const {
225             i++;
226             if(i<min)
227             {
228                 flag=false;
229                 return true;
230             }
231             else if(i>=min && i<=max)
232             {
233                 return flag=true;
234             }
235             else
236                 return flag=false;
237         }
238         T const min;
239         T const max;
240
241         // silence MSVC warning C4512: assignment operator could not be generated
242         BOOST_DELETED_FUNCTION(kwd_finite_iterator& operator= (kwd_finite_iterator const&))
243     };
244
245     template <typename T>
246     struct kwd_infinite_iterator // handles kwd(min, inf)[p]
247     {
248         kwd_infinite_iterator(T const min)
249           : min BOOST_PREVENT_MACRO_SUBSTITUTION (min) {}
250
251         typedef T type;
252         bool flag_init() const { return min==0; }
253         bool register_successful_parse(bool &flag,T &i) const {
254             i++;
255             flag = i>=min;
256             return true;
257         }
258         T const min;
259
260         // silence MSVC warning C4512: assignment operator could not be generated
261         BOOST_DELETED_FUNCTION(kwd_infinite_iterator& operator= (kwd_infinite_iterator const&))
262     };
263
264     // This class enables the transportation of parameters needed to call
265     // the occurrence constraint checker from higher level calls
266     // It also serves to select the correct parse function call
267     // of the keyword parser. The implementation changes depending if it is
268     // called form a keyword parsing loop or not.
269     template <typename Skipper, typename NoCasePass>
270     struct skipper_keyword_marker
271     {
272         typedef NoCasePass no_case_pass;
273
274         skipper_keyword_marker(Skipper const &skipper,bool &flag,int &counter) :
275               skipper(skipper)
276             , flag(flag)
277             , counter(counter)
278             {}
279
280         const Skipper &skipper;
281         bool &flag;
282         int &counter;
283     };
284
285     template <typename Subject, typename KeywordType, typename LoopIter , typename NoCase, typename Distinct >
286     struct kwd_parser : spirit::qi::unary_parser<kwd_parser<Subject, KeywordType, LoopIter , NoCase, Distinct > >
287     {
288         struct kwd_parser_id;
289
290         typedef Subject subject_type;
291         typedef NoCase no_case_keyword;
292         typedef Distinct distinct;
293
294         typedef typename
295             remove_const<typename traits::char_type_of<KeywordType>::type>::type
296         char_type;
297
298         typedef std::basic_string<char_type> keyword_type;
299
300         template <typename Context, typename Iterator>
301         struct attribute
302         {
303             typedef typename
304             traits::build_std_vector<
305                 typename traits::attribute_of<
306                 Subject, Context, Iterator>::type
307                         >::type
308                 type;
309         };
310
311
312         kwd_parser(Subject const& subject
313            , typename add_reference<KeywordType>::type keyword
314            , LoopIter const& iter)
315           : subject(subject), iter(iter), keyword(keyword) {}
316
317         template<typename CharEncoding>
318         kwd_parser(Subject const& subject
319            , typename add_reference<KeywordType>::type keyword
320            , LoopIter const& iter, CharEncoding encoding)
321           : subject(subject), iter(iter), keyword(keyword,encoding) {}
322
323
324         // Call the subject parser on a non container attribute
325         template <typename Iterator, typename Context
326           , typename Skipper, typename Attribute>
327         bool parse_impl(Iterator& first, Iterator const& last
328           , Context& context, Skipper const& skipper
329           , Attribute& attr,mpl::false_) const
330         {
331             return subject.parse(first,last,context,skipper,attr);
332         }
333
334         // Call the subject parser on a container attribute
335         template <typename Iterator, typename Context
336           , typename Skipper, typename Attribute>
337         bool parse_impl(Iterator& first, Iterator const& last
338           , Context& context, Skipper const& skipper
339           , Attribute& attr,mpl::true_) const
340         {
341
342             // synthesized attribute needs to be default constructed
343             typename traits::container_value<Attribute>::type val =
344                 typename traits::container_value<Attribute>::type();
345
346             Iterator save = first;
347             bool r = subject.parse(first,last,context,skipper, val);
348             if (r)
349             {
350                 // push the parsed value into our attribute
351                 r = traits::push_back(attr, val);
352                 if (!r)
353                     first = save;
354             }
355             return r;
356         }
357
358        template <typename Iterator, typename Context
359           , typename Skipper, typename Attribute,typename NoCasePass>
360         bool parse(Iterator& first, Iterator const& last
361           , Context& context, skipper_keyword_marker<Skipper,NoCasePass> const& skipper
362           , Attribute &attr) const
363         {
364
365             typedef typename traits::attribute_of<
366                 Subject, Context, Iterator>::type
367                 subject_attribute;
368
369             typedef typename mpl::and_<
370              traits::is_container<Attribute>
371             , mpl::not_< traits::is_weak_substitute< subject_attribute,Attribute > >
372             >::type predicate;
373
374             if((no_case_keyword::value && NoCasePass::value) || !NoCasePass::value)
375             {
376                 if(parse_impl(first,last,context,skipper.skipper,attr, predicate()))
377                     return iter.register_successful_parse(skipper.flag,skipper.counter);
378             }
379             return false;
380         }
381
382         template <typename Iterator, typename Context
383           , typename Skipper, typename Attribute>
384         bool parse(Iterator& first, Iterator const& last
385           , Context& context, Skipper const& skipper
386           , Attribute& attr) const
387           {
388               typedef typename traits::attribute_of<
389                 Subject, Context, Iterator>::type
390                 subject_attribute;
391
392             typedef typename mpl::and_<
393             traits::is_container<Attribute>
394             , mpl::not_< traits::is_weak_substitute< subject_attribute,Attribute > >
395             >::type predicate;
396
397
398             // Parse the keyword
399             bool flag = iter.flag_init();
400             int counter = 0;
401             Iterator save = first;
402             spirit::qi::skip_over(first, last, skipper);
403             if(keyword.parse(first,last,context,skipper,unused)){
404                 if((!distinct::value) || skipper.parse(first,last,unused,unused,unused)){
405                   // Followed by the subject parser
406                   spirit::qi::skip_over(first, last, skipper);
407                   if(parse_impl(first,last,context,skipper,attr, predicate()))
408                   {
409                       return iter.register_successful_parse(flag,counter);
410                   }
411                 }
412             }
413             first = save;
414             return flag;
415           }
416
417
418         template <typename Context>
419           info what(Context& context) const
420           {
421             if(distinct::value){
422               if(no_case_keyword::value)
423                 return info("idkwd", subject.what(context));
424               else
425                 return info("dkwd", subject.what(context));
426             }
427             else
428             {
429               if(no_case_keyword::value)
430                 return info("ikwd", subject.what(context));
431               else
432                 return info("kwd", subject.what(context));
433             }
434         }
435
436         Subject subject;
437         LoopIter iter;
438
439         typedef typename mpl::if_<
440                 no_case_keyword,
441                 spirit::qi::no_case_literal_string< KeywordType, true>,
442                 spirit::qi::literal_string<KeywordType, true> >::type keyword_string_type;
443         keyword_string_type keyword;
444
445         // silence MSVC warning C4512: assignment operator could not be generated
446         BOOST_DELETED_FUNCTION(kwd_parser& operator= (kwd_parser const&))
447
448     private:
449         template <typename Iterator, typename Context, typename Skipper>
450         static spirit::qi::detail::fail_function<Iterator, Context, Skipper>
451         fail_function(
452             Iterator& first, Iterator const& last
453           , Context& context, Skipper const& skipper)
454         {
455             return spirit::qi::detail::fail_function<Iterator, Context, Skipper>
456                 (first, last, context, skipper);
457         }
458
459
460     };
461
462 template <typename Subject, typename KeywordType, typename LoopIter, typename Distinct>
463     struct complex_kwd_parser : spirit::qi::unary_parser<complex_kwd_parser<Subject, KeywordType, LoopIter, Distinct > >
464     {
465         struct complex_kwd_parser_id;
466         typedef Subject subject_type;
467         typedef Distinct distinct;
468
469         template <typename Context, typename Iterator>
470         struct attribute
471         {
472             typedef typename
473             traits::build_std_vector<
474                 typename traits::attribute_of<
475                 Subject, Context, Iterator>::type
476                         >::type
477                 type;
478         };
479
480
481         complex_kwd_parser(Subject const& subject
482            , typename add_reference<KeywordType>::type keyword
483            , LoopIter const& iter)
484           : subject(subject), iter(iter), keyword(keyword) {}
485
486         // Call the subject parser on a non container attribute
487         template <typename Iterator, typename Context
488           , typename Skipper, typename Attribute>
489         bool parse_impl(Iterator& first, Iterator const& last
490           , Context& context, Skipper const& skipper
491           , Attribute& attr,mpl::false_) const
492         {
493             return subject.parse(first,last,context,skipper,attr);
494         }
495
496         // Call the subject parser on a container attribute
497         template <typename Iterator, typename Context
498           , typename Skipper, typename Attribute>
499         bool parse_impl(Iterator& first, Iterator const& last
500           , Context& context, Skipper const& skipper
501           , Attribute& attr,mpl::true_) const
502         {
503
504             // synthesized attribute needs to be default constructed
505             typename traits::container_value<Attribute>::type val =
506                 typename traits::container_value<Attribute>::type();
507
508             Iterator save = first;
509             bool r = subject.parse(first,last,context,skipper, val);
510             if (r)
511             {
512                 // push the parsed value into our attribute
513                 r = traits::push_back(attr, val);
514                 if (!r)
515                     first = save;
516             }
517             return r;
518         }
519
520        template <typename Iterator, typename Context
521           , typename Skipper, typename Attribute,typename NoCasePass>
522         bool parse(Iterator& first, Iterator const& last
523           , Context& context, skipper_keyword_marker<Skipper,NoCasePass> const& skipper
524           , Attribute &attr) const
525         {
526
527             typedef typename traits::attribute_of<
528                 Subject, Context, Iterator>::type
529                 subject_attribute;
530
531             typedef typename mpl::and_<
532              traits::is_container<Attribute>
533             , mpl::not_< traits::is_weak_substitute< subject_attribute,Attribute > >
534             >::type predicate;
535
536             if(parse_impl(first,last,context,skipper.skipper,attr, predicate()))
537                 return iter.register_successful_parse(skipper.flag,skipper.counter);
538             return false;
539         }
540
541         template <typename Iterator, typename Context
542           , typename Skipper, typename Attribute>
543         bool parse(Iterator& first, Iterator const& last
544           , Context& context, Skipper const& skipper
545           , Attribute& attr) const
546           {
547               typedef typename traits::attribute_of<
548                 Subject, Context, Iterator>::type
549                 subject_attribute;
550
551             typedef typename mpl::and_<
552             traits::is_container<Attribute>
553             , mpl::not_< traits::is_weak_substitute< subject_attribute,Attribute > >
554             >::type predicate;
555
556
557             // Parse the keyword
558             bool flag = iter.flag_init();
559             int counter = 0;
560             Iterator save = first;
561             spirit::qi::skip_over(first, last, skipper);
562             if(keyword.parse(first,last,context,skipper,unused)){
563               if( !distinct::value || skipper.parse(first,last,unused,unused,unused)){
564                 // Followed by the subject parser
565                 spirit::qi::skip_over(first, last, skipper);
566                 if(parse_impl(first,last,context,skipper,attr, predicate()))
567                 {
568                   return iter.register_successful_parse(flag,counter);
569                 }
570               }
571             }
572             first = save;
573             return flag;
574           }
575
576
577         template <typename Context>
578         info what(Context& context) const
579         {
580            if(distinct::value)
581             return info("dkwd", subject.what(context));
582            else
583             return info("kwd", subject.what(context));
584         }
585
586         Subject subject;
587         LoopIter iter;
588
589         KeywordType keyword;
590
591         // silence MSVC warning C4512: assignment operator could not be generated
592         BOOST_DELETED_FUNCTION(complex_kwd_parser& operator= (complex_kwd_parser const&))
593
594     private:
595         template <typename Iterator, typename Context, typename Skipper>
596         static spirit::qi::detail::fail_function<Iterator, Context, Skipper>
597         fail_function(
598             Iterator& first, Iterator const& last
599           , Context& context, Skipper const& skipper)
600         {
601             return spirit::qi::detail::fail_function<Iterator, Context, Skipper>
602                 (first, last, context, skipper);
603         }
604
605     };
606
607 }}}}
608
609 ///////////////////////////////////////////////////////////////////////////////
610 namespace boost { namespace spirit { namespace qi
611 {
612
613     ///////////////////////////////////////////////////////////////////////////
614     // Parser generators: make_xxx function (objects)
615     ///////////////////////////////////////////////////////////////////////////
616
617     template <typename T1, typename T2,  typename Subject, typename Modifiers, typename Distinct, typename MakeDirectiveHelper>
618     struct make_directive_internal_2_args
619     {
620
621         // is the keyword a string keyword ?
622         typedef typename traits::is_string<T1> is_string_kwd_type;
623         // make the keyword type
624         typedef typename mpl::if_< is_string_kwd_type ,
625                                    T1 ,
626                                    typename result_of::compile<qi::domain, T1>::type
627                                  >::type keyword_type;
628
629         typedef typename add_const<keyword_type>::type const_keyword;
630         // select the pass iterator type
631         typedef typename MakeDirectiveHelper::iterator_type iterator_type;
632         // determine if a no case modifier applies to the context
633         typedef has_modifier<Modifiers, tag::char_code_base<tag::no_case> > no_case;
634         // Determine the full type of the kwd / complex_kwd directive
635         typedef typename
636              mpl::if_<
637                 is_string_kwd_type,
638                 repository::qi::kwd_parser<Subject, const_keyword, iterator_type, no_case, Distinct >,
639                 repository::qi::complex_kwd_parser<Subject, const_keyword, iterator_type, Distinct >
640                      >::type result_type;
641
642         // Return a kwd parser object
643         template <typename Terminal>
644         result_type create_kwd_string(Terminal const &term, Subject const & subject, boost::mpl::true_ ) const
645         {
646             typename spirit::detail::get_encoding<Modifiers,
647                 spirit::char_encoding::standard>::type encoding;
648            return result_type(subject
649                         ,MakeDirectiveHelper::make_iterator(term.args)
650                         ,encoding
651                         );
652         }
653         template <typename Terminal>
654         result_type create_kwd_string(Terminal const &term, Subject const & subject, boost::mpl::false_ ) const
655         {
656            return result_type(subject
657                         ,fusion::at_c<0>(term.args)
658                         ,MakeDirectiveHelper::make_iterator(term.args)
659                         );
660         }
661         template <typename Terminal>
662         result_type create_kwd(Terminal const &term, Subject const & subject, Modifiers const& /*modifiers*/, boost::mpl::true_ ) const
663         {
664            return create_kwd_string(term,subject,no_case());
665         }
666         // Return a complex_kwd parser object
667         template <typename Terminal>
668         result_type create_kwd(Terminal const &term , Subject const & subject, Modifiers const& modifiers, boost::mpl::false_ ) const
669         {
670            return result_type(subject
671                         ,compile<qi::domain>(fusion::at_c<0>(term.args),modifiers)
672                         ,MakeDirectiveHelper::make_iterator(term.args)                        
673                         );
674         }
675         // Select which object type to return
676         template <typename Terminal>
677         result_type operator()(
678             Terminal const& term, Subject const& subject, Modifiers const& modifiers) const
679         {
680             return create_kwd(term, subject, modifiers, is_string_kwd_type());
681         }
682
683     };
684
685      // Directive kwd(key)[p]
686     template <typename T1,  typename Subject, typename Modifiers, typename Distinct>
687     struct make_directive_internal
688     {
689         // is the keyword a string keyword ?
690         typedef typename traits::is_string<T1> is_string_kwd_type;
691         // make the keyword type
692         typedef typename mpl::if_< is_string_kwd_type ,
693                                    T1 ,
694                                    typename result_of::compile<qi::domain, T1, Modifiers>::type
695                                  >::type keyword_type;
696
697         typedef typename add_const<keyword_type>::type const_keyword;
698         // select the pass iterator type
699         typedef repository::qi::kwd_pass_iterator<int> iterator_type;
700         // determine if a no case modifier applies to the context
701         typedef has_modifier<Modifiers, tag::char_code_base<tag::no_case> > no_case;
702         // Determine the full type of the kwd / complex_kwd directive
703         typedef typename
704              mpl::if_<
705                 is_string_kwd_type,
706                 repository::qi::kwd_parser<Subject, const_keyword, iterator_type, no_case, Distinct >,
707                 repository::qi::complex_kwd_parser<Subject, const_keyword, iterator_type, Distinct>
708                      >::type result_type;
709
710         // Return a kwd parser object
711         template <typename Terminal>
712         result_type create_kwd_string(Terminal const &term, Subject const & subject, boost::mpl::true_) const
713         {
714             typename spirit::detail::get_encoding<Modifiers,
715                 spirit::char_encoding::standard>::type encoding;
716
717             return result_type(subject
718                         ,fusion::at_c<0>(term.args)
719                         ,iterator_type()
720                         ,encoding
721                         );
722
723         }
724         template <typename Terminal>
725         result_type create_kwd_string(Terminal const &term, Subject const & subject, boost::mpl::false_) const
726         {
727             return result_type(subject
728                         ,fusion::at_c<0>(term.args)
729                         ,iterator_type()
730                         );
731         }
732         template <typename Terminal>
733         result_type create_kwd(Terminal const &term, Subject const & subject, Modifiers const& /*modifiers*/, boost::mpl::true_ ) const
734         {
735            return create_kwd_string(term,subject,no_case());
736         }
737         // Return a complex_kwd parser object
738         template <typename Terminal>
739         result_type create_kwd(Terminal const &term , Subject const & subject, Modifiers const& modifiers, boost::mpl::false_ ) const
740         {
741            return result_type(subject
742                         ,compile<qi::domain>(fusion::at_c<0>(term.args),modifiers)
743                         ,iterator_type()
744                         );
745         }
746         // Select which object type to return
747         template <typename Terminal>
748         result_type operator()(
749             Terminal const& term, Subject const& subject, Modifiers const& modifiers ) const
750         {
751             return create_kwd(term, subject, modifiers, is_string_kwd_type());
752         }
753     };
754
755     template <typename T1,  typename Subject, typename Modifiers>
756     struct make_directive<
757         terminal_ex<repository::tag::kwd, fusion::vector1<T1> >, Subject, Modifiers>
758     {
759         typedef make_directive_internal<T1, Subject, Modifiers, mpl::false_> make_directive_type;
760         typedef typename make_directive_type::result_type result_type;
761         template <typename Terminal>
762         result_type operator()(
763             Terminal const& term, Subject const& subject, Modifiers const& modifiers) const
764         {
765
766             return make_directive_type()(term, subject, modifiers);
767         }
768
769     };
770  
771    template <typename T1,  typename Subject, typename Modifiers>
772     struct make_directive<
773         terminal_ex<repository::tag::dkwd, fusion::vector1<T1> >, Subject, Modifiers>
774     {
775         typedef make_directive_internal<T1, Subject, Modifiers, mpl::true_> make_directive_type;
776         typedef typename make_directive_type::result_type result_type;
777         template <typename Terminal>
778         result_type operator()(
779             Terminal const& term, Subject const& subject, Modifiers const& modifiers) const
780         {
781
782             return make_directive_type()(term, subject, modifiers);
783         }
784
785     };
786  
787
788
789     // Directive ikwd(key)[p]
790     template <typename T1,  typename Subject, typename Modifiers>
791     struct make_directive<
792         terminal_ex<repository::tag::ikwd, fusion::vector1<T1> >, Subject, Modifiers>
793     {
794         typedef typename add_const<T1>::type const_keyword;
795         typedef repository::qi::kwd_pass_iterator<int> iterator_type;
796
797         typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, mpl::true_, mpl::false_ > result_type;
798
799         template <typename Terminal>
800         result_type operator()(
801             Terminal const& term, Subject const& subject,  unused_type) const
802         {
803             typename spirit::detail::get_encoding<Modifiers,
804                 spirit::char_encoding::standard>::type encoding;
805
806             return result_type(subject
807                         ,fusion::at_c<0>(term.args)
808                         ,iterator_type()
809                         ,encoding
810                         );
811         }
812     };
813
814     template <typename T1,  typename Subject, typename Modifiers>
815     struct make_directive<
816         terminal_ex<repository::tag::idkwd, fusion::vector1<T1> >, Subject, Modifiers>
817     {
818         typedef typename add_const<T1>::type const_keyword;
819         typedef repository::qi::kwd_pass_iterator<int> iterator_type;
820
821         typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, mpl::true_, mpl::true_ > result_type;
822
823         template <typename Terminal>
824         result_type operator()(
825             Terminal const& term, Subject const& subject, unused_type) const
826         {
827             typename spirit::detail::get_encoding<Modifiers,
828                 spirit::char_encoding::standard>::type encoding;
829
830             return result_type(subject
831                         ,fusion::at_c<0>(term.args)
832                         ,iterator_type()
833                         ,encoding
834                         );
835         }
836     };
837
838     // Directive kwd(key,exact)[p]
839         template <typename T>
840     struct make_exact_helper
841     { 
842         typedef repository::qi::kwd_exact_iterator<T> iterator_type;
843         template<typename Args>
844         static iterator_type make_iterator(Args const& args)
845         {
846           return iterator_type(fusion::at_c<1>(args));
847         }
848     };
849
850     template <typename T1, typename T2,  typename Subject, typename Modifiers>
851     struct make_directive<
852         terminal_ex<repository::tag::kwd, fusion::vector2<T1,T2> >, Subject, Modifiers>
853     {
854         typedef make_directive_internal_2_args< T1
855                                               , T2
856                                               , Subject
857                                               , Modifiers
858                                               , mpl::false_
859                                               , make_exact_helper<T2>
860                                               > make_directive_type;
861         typedef typename make_directive_type::result_type result_type;
862         template <typename Terminal>
863         result_type operator()(
864             Terminal const& term, Subject const& subject, Modifiers const& modifiers) const
865         {
866
867             return make_directive_type()(term,subject, modifiers);
868         }
869
870     };
871   
872     template <typename T1, typename T2,  typename Subject, typename Modifiers>
873     struct make_directive<
874         terminal_ex<repository::tag::dkwd, fusion::vector2<T1,T2> >, Subject, Modifiers>
875     {
876          typedef make_directive_internal_2_args< T1
877                                               , T2
878                                               , Subject
879                                               , Modifiers
880                                               , mpl::true_
881                                               , make_exact_helper<T2>
882                                               > make_directive_type;
883         
884         typedef typename make_directive_type::result_type result_type;
885         template <typename Terminal>
886         result_type operator()(
887             Terminal const& term, Subject const& subject, Modifiers const& modifiers) const
888         {
889
890             return make_directive_type()(term, subject, modifiers);
891         }
892
893     };
894   
895
896     // Directive ikwd(key,exact)[p]
897     template <typename T1, typename T2,  typename Subject, typename Modifiers>
898     struct make_directive<
899         terminal_ex<repository::tag::ikwd, fusion::vector2<T1,T2> >, Subject, Modifiers>
900     {
901         typedef typename add_const<T1>::type const_keyword;
902         typedef repository::qi::kwd_exact_iterator<T2> iterator_type;
903
904         typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, mpl::true_, mpl::false_ > result_type;
905
906         template <typename Terminal>
907         result_type operator()(
908             Terminal const& term, Subject const& subject, Modifiers const& /*modifiers*/) const
909         {
910             typename spirit::detail::get_encoding<Modifiers,
911                 spirit::char_encoding::standard>::type encoding;
912             return result_type(subject
913                         , fusion::at_c<0>(term.args)
914                         , fusion::at_c<1>(term.args)
915                         , encoding
916                         );
917         }
918     };
919
920     template <typename T1, typename T2,  typename Subject, typename Modifiers>
921     struct make_directive<
922         terminal_ex<repository::tag::idkwd, fusion::vector2<T1,T2> >, Subject, Modifiers>
923     {
924         typedef typename add_const<T1>::type const_keyword;
925         typedef repository::qi::kwd_exact_iterator<T2> iterator_type;
926
927         typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, mpl::true_, mpl::true_ > result_type;
928
929         template <typename Terminal>
930         result_type operator()(
931             Terminal const& term, Subject const& subject, Modifiers const& /*modifiers*/) const
932         {
933             typename spirit::detail::get_encoding<Modifiers,
934                 spirit::char_encoding::standard>::type encoding;
935             return result_type(subject
936                         , fusion::at_c<0>(term.args)
937                         , fusion::at_c<1>(term.args)
938                         , encoding
939                         );
940         }
941     };
942
943
944     // Directive kwd(min, max)[p]
945
946     template <typename T>
947     struct make_finite_helper
948     { 
949         typedef repository::qi::kwd_finite_iterator<T> iterator_type;
950         template<typename Args>
951         static iterator_type make_iterator(Args const& args)
952         {
953           return iterator_type(fusion::at_c<1>(args),fusion::at_c<2>(args));
954         }
955
956     };
957
958     template <typename T1, typename T2,  typename Subject, typename Modifiers>
959     struct make_directive<
960         terminal_ex<repository::tag::kwd, fusion::vector3<T1,T2,T2> >, Subject, Modifiers>
961     {
962         typedef make_directive_internal_2_args< T1
963                                               , T2
964                                               , Subject
965                                               , Modifiers
966                                               , mpl::false_
967                                               , make_finite_helper<T2>
968                                               > make_directive_type;
969         
970         
971         typedef typename make_directive_type::result_type result_type;
972         template <typename Terminal>
973         result_type operator()(
974             Terminal const& term, Subject const& subject, Modifiers const& modifiers) const
975         {
976
977             return make_directive_type()(term,subject, modifiers);
978         }
979
980     };
981   
982     template <typename T1, typename T2,  typename Subject, typename Modifiers>
983     struct make_directive<
984         terminal_ex<repository::tag::dkwd, fusion::vector3<T1,T2,T2> >, Subject, Modifiers>
985     {
986        
987         typedef make_directive_internal_2_args< T1
988                                               , T2
989                                               , Subject
990                                               , Modifiers
991                                               , mpl::true_
992                                               , make_finite_helper<T2>
993                                               > make_directive_type;
994  
995         typedef typename make_directive_type::result_type result_type;
996         template <typename Terminal>
997         result_type operator()(
998             Terminal const& term, Subject const& subject, Modifiers const& modifiers) const
999         {
1000
1001             return make_directive_type()(term,subject, modifiers);
1002         }
1003
1004     };
1005
1006     // Directive ikwd(min, max)[p]
1007     template <typename T1, typename T2, typename Subject, typename Modifiers>
1008     struct make_directive<
1009         terminal_ex<repository::tag::ikwd, fusion::vector3< T1, T2, T2> >, Subject, Modifiers>
1010     {
1011         typedef typename add_const<T1>::type const_keyword;
1012         typedef repository::qi::kwd_finite_iterator<T2> iterator_type;
1013
1014         typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, mpl::true_, mpl::false_ > result_type;
1015
1016         template <typename Terminal>
1017         result_type operator()(
1018             Terminal const& term, Subject const& subject, unused_type) const
1019         {
1020
1021             typename spirit::detail::get_encoding<Modifiers,
1022                 spirit::char_encoding::standard>::type encoding;
1023             return result_type(subject, fusion::at_c<0>(term.args),
1024                 iterator_type(
1025                     fusion::at_c<1>(term.args)
1026                   , fusion::at_c<2>(term.args)
1027                   , encoding
1028                 )
1029             );
1030         }
1031     };
1032
1033     template <typename T1, typename T2, typename Subject, typename Modifiers>
1034     struct make_directive<
1035         terminal_ex<repository::tag::idkwd, fusion::vector3< T1, T2, T2> >, Subject, Modifiers>
1036     {
1037         typedef typename add_const<T1>::type const_keyword;
1038         typedef repository::qi::kwd_finite_iterator<T2> iterator_type;
1039
1040         typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, mpl::true_, mpl::true_ > result_type;
1041
1042         template <typename Terminal>
1043         result_type operator()(
1044             Terminal const& term, Subject const& subject, unused_type) const
1045         {
1046
1047             typename spirit::detail::get_encoding<Modifiers,
1048                 spirit::char_encoding::standard>::type encoding;
1049             return result_type(subject, fusion::at_c<0>(term.args),
1050                 iterator_type(
1051                     fusion::at_c<1>(term.args)
1052                   , fusion::at_c<2>(term.args)
1053                   , encoding
1054                 )
1055             );
1056         }
1057     };
1058
1059
1060     // Directive kwd(min, inf)[p]
1061
1062     template <typename T>
1063     struct make_infinite_helper
1064     { 
1065         typedef repository::qi::kwd_infinite_iterator<T> iterator_type;
1066         template<typename Args>
1067         static iterator_type make_iterator(Args const& args)
1068         {
1069           return iterator_type(fusion::at_c<1>(args));
1070         }
1071
1072     };
1073
1074
1075     template <typename T1, typename T2,  typename Subject, typename Modifiers>
1076     struct make_directive<
1077         terminal_ex<repository::tag::kwd, fusion::vector3<T1,T2,inf_type> >, Subject, Modifiers>
1078     {
1079          typedef make_directive_internal_2_args< T1
1080                                               , T2
1081                                               , Subject
1082                                               , Modifiers
1083                                               , mpl::false_
1084                                               , make_infinite_helper<T2>
1085                                               > make_directive_type;
1086         
1087         typedef typename make_directive_type::result_type result_type;
1088         template <typename Terminal>
1089         result_type operator()(
1090             Terminal const& term, Subject const& subject, unused_type) const
1091         {
1092
1093             return make_directive_type()(term,subject, unused_type());
1094         }
1095
1096     };
1097   
1098     template <typename T1, typename T2,  typename Subject, typename Modifiers>
1099     struct make_directive<
1100         terminal_ex<repository::tag::dkwd, fusion::vector3<T1,T2,inf_type> >, Subject, Modifiers>
1101     {
1102       typedef make_directive_internal_2_args< T1
1103                                               , T2
1104                                               , Subject
1105                                               , Modifiers
1106                                               , mpl::false_
1107                                               , make_infinite_helper<T2>
1108                                               > make_directive_type;
1109     
1110         typedef typename make_directive_type::result_type result_type;
1111         template <typename Terminal>
1112         result_type operator()(
1113             Terminal const& term, Subject const& subject, unused_type) const
1114         {
1115
1116             return make_directive_type()(term,subject, unused_type());
1117         }
1118
1119     };
1120
1121
1122     // Directive ikwd(min, inf)[p]
1123     template <typename T1, typename T2, typename Subject, typename Modifiers>
1124     struct make_directive<
1125         terminal_ex<repository::tag::ikwd
1126         , fusion::vector3<T1, T2, inf_type> >, Subject, Modifiers>
1127     {
1128         typedef typename add_const<T1>::type const_keyword;
1129         typedef repository::qi::kwd_infinite_iterator<T2> iterator_type;
1130
1131         typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, mpl::true_, mpl::false_ > result_type;
1132
1133         template <typename Terminal>
1134         result_type operator()(
1135             Terminal const& term, Subject const& subject, unused_type) const
1136         {
1137             typename spirit::detail::get_encoding<Modifiers,
1138                 spirit::char_encoding::standard>::type encoding;
1139
1140             return result_type(subject
1141                 , fusion::at_c<0>(term.args)
1142                 , fusion::at_c<1>(term.args)
1143                 , encoding
1144                 );
1145         }
1146     };
1147
1148   template <typename T1, typename T2, typename Subject, typename Modifiers>
1149     struct make_directive<
1150         terminal_ex<repository::tag::idkwd
1151         , fusion::vector3<T1, T2, inf_type> >, Subject, Modifiers>
1152     {
1153         typedef typename add_const<T1>::type const_keyword;
1154         typedef repository::qi::kwd_infinite_iterator<T2> iterator_type;
1155
1156         typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, mpl::true_, mpl::true_ > result_type;
1157
1158         template <typename Terminal>
1159         result_type operator()(
1160             Terminal const& term, Subject const& subject, unused_type) const
1161         {
1162             typename spirit::detail::get_encoding<Modifiers,
1163                 spirit::char_encoding::standard>::type encoding;
1164
1165             return result_type(subject
1166                 , fusion::at_c<0>(term.args)
1167                 , fusion::at_c<1>(term.args)
1168                 , encoding
1169                 );
1170         }
1171     };
1172
1173
1174 }}}
1175
1176 namespace boost { namespace spirit { namespace traits
1177 {
1178     template <typename Subject, typename KeywordType
1179             , typename LoopIter, typename NoCase , typename Distinct>
1180     struct has_semantic_action<
1181             repository::qi::kwd_parser< Subject, KeywordType, LoopIter, NoCase, Distinct > >
1182       : unary_has_semantic_action<Subject> {};
1183
1184     template <typename Subject, typename KeywordType
1185             , typename LoopIter, typename Distinct >
1186     struct has_semantic_action<
1187             repository::qi::complex_kwd_parser< Subject, KeywordType, LoopIter, Distinct > >
1188       : unary_has_semantic_action<Subject> {};
1189
1190     template <typename Subject, typename KeywordType
1191               , typename LoopIter, typename NoCase, typename Attribute, typename Context
1192                 , typename Iterator, typename Distinct>
1193     struct handles_container<repository::qi::kwd_parser<Subject, KeywordType, LoopIter, NoCase, Distinct>, Attribute
1194         , Context, Iterator>
1195       : unary_handles_container<Subject, Attribute, Context, Iterator> {};
1196
1197     template <typename Subject, typename KeywordType
1198                 , typename LoopIter
1199                 , typename Attribute, typename Context
1200                 , typename Iterator, typename Distinct>
1201     struct handles_container<repository::qi::complex_kwd_parser<Subject, KeywordType, LoopIter, Distinct>, Attribute
1202         , Context, Iterator>
1203       : unary_handles_container<Subject, Attribute, Context, Iterator> {};
1204
1205 }}}
1206
1207 #if defined(_MSC_VER)
1208 # pragma warning(pop)
1209 #endif
1210
1211 #endif
1212