1 /*
2  *
3  * Copyright (c) 2004
4  * John Maddock
5  *
6  * Use, modification and distribution are subject to the
7  * Boost Software License, Version 1.0. (See accompanying file
8  * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9  *
10  */
11 
12  /*
13   *   LOCATION:    see http://www.boost.org for most recent version.
14   *   FILE         concepts.hpp
15   *   VERSION      see <boost/version.hpp>
16   *   DESCRIPTION: Declares regular expression concepts.
17   */
18 
19 #ifndef BOOST_REGEX_CONCEPTS_HPP_INCLUDED
20 #define BOOST_REGEX_CONCEPTS_HPP_INCLUDED
21 
22 #include <boost/concept_archetype.hpp>
23 #include <boost/concept_check.hpp>
24 #include <boost/type_traits/is_enum.hpp>
25 #include <boost/type_traits/is_base_and_derived.hpp>
26 #include <boost/static_assert.hpp>
27 #ifndef BOOST_TEST_TR1_REGEX
28 #include <boost/regex.hpp>
29 #endif
30 #include <bitset>
31 #include <vector>
32 #include <iostream>
33 
34 namespace boost{
35 
36 //
37 // bitmask_archetype:
38 // this can be either an integer type, an enum, or a std::bitset,
39 // we use the latter as the architype as it offers the "strictest"
40 // of the possible interfaces:
41 //
42 typedef std::bitset<512> bitmask_archetype;
43 //
44 // char_architype:
45 // A strict model for the character type interface.
46 //
47 struct char_architype
48 {
49    // default constructable:
50    char_architype();
51    // copy constructable / assignable:
52    char_architype(const char_architype&);
53    char_architype& operator=(const char_architype&);
54    // constructable from an integral value:
55    char_architype(unsigned long val);
56    // comparable:
57    bool operator==(const char_architype&)const;
58    bool operator!=(const char_architype&)const;
59    bool operator<(const char_architype&)const;
60    bool operator<=(const char_architype&)const;
61    bool operator>=(const char_architype&)const;
62    bool operator>(const char_architype&)const;
63    // conversion to integral type:
64    operator long()const;
65 };
66 //
67 // char_architype can not be used with basic_string:
68 //
69 } // namespace boost
70 namespace std{
71    template<> struct char_traits<boost::char_architype>
72    {
73       // The intent is that this template is not instantiated,
74       // but this typedef gives us a chance of compilation in
75       // case it is:
76       typedef boost::char_architype char_type;
77    };
78 }
79 //
80 // Allocator architype:
81 //
82 template <class T>
83 class allocator_architype
84 {
85 public:
86    typedef T* pointer;
87    typedef const T* const_pointer;
88    typedef T& reference;
89    typedef const T& const_reference;
90    typedef T value_type;
91    typedef unsigned size_type;
92    typedef int difference_type;
93 
94    template <class U>
95    struct rebind
96    {
97       typedef allocator_architype<U> other;
98    };
99 
100    pointer address(reference r);
101    const_pointer address(const_reference r);
102    pointer allocate(size_type);
103    pointer allocate(size_type, pointer);
104    void deallocate(pointer, size_type);
105    size_type max_size()const;
106 
107    allocator_architype();
108    allocator_architype(const allocator_architype&);
109 
110    template <class Other>
111    allocator_architype(const allocator_architype<Other>&);
112 
113    void construct(pointer, const_reference);
114    void destroy(pointer);
115 };
116 
117 template <class T>
118 bool operator == (const allocator_architype<T>&, const allocator_architype<T>&);
119 template <class T>
120 bool operator != (const allocator_architype<T>&, const allocator_architype<T>&);
121 
122 namespace boost{
123 //
124 // regex_traits_architype:
125 // A strict interpretation of the regular expression traits class requirements.
126 //
127 template <class charT>
128 struct regex_traits_architype
129 {
130 public:
131    regex_traits_architype();
132    typedef charT char_type;
133    // typedef std::size_t size_type;
134    typedef std::vector<char_type> string_type;
135    typedef copy_constructible_archetype<assignable_archetype<> > locale_type;
136    typedef bitmask_archetype char_class_type;
137 
lengthboost::regex_traits_architype138    static std::size_t length(const char_type* ) { return 0; }
139 
translateboost::regex_traits_architype140    charT translate(charT ) const { return charT(); }
translate_nocaseboost::regex_traits_architype141    charT translate_nocase(charT ) const { return static_object<charT>::get(); }
142 
143    template <class ForwardIterator>
transformboost::regex_traits_architype144    string_type transform(ForwardIterator , ForwardIterator ) const
145    { return static_object<string_type>::get(); }
146    template <class ForwardIterator>
transform_primaryboost::regex_traits_architype147    string_type transform_primary(ForwardIterator , ForwardIterator ) const
148    { return static_object<string_type>::get(); }
149 
150    template <class ForwardIterator>
lookup_classnameboost::regex_traits_architype151    char_class_type lookup_classname(ForwardIterator , ForwardIterator ) const
152    { return static_object<char_class_type>::get(); }
153    template <class ForwardIterator>
lookup_collatenameboost::regex_traits_architype154    string_type lookup_collatename(ForwardIterator , ForwardIterator ) const
155    { return static_object<string_type>::get(); }
156 
isctypeboost::regex_traits_architype157    bool isctype(charT, char_class_type) const
158    { return false; }
valueboost::regex_traits_architype159    int value(charT, int) const
160    { return 0; }
161 
imbueboost::regex_traits_architype162    locale_type imbue(locale_type l)
163    { return l; }
getlocboost::regex_traits_architype164    locale_type getloc()const
165    { return static_object<locale_type>::get(); }
166 
167 private:
168    // this type is not copyable:
169    regex_traits_architype(const regex_traits_architype&);
170    regex_traits_architype& operator=(const regex_traits_architype&);
171 };
172 
173 //
174 // alter this to std::tr1, to test a std implementation:
175 //
176 #ifndef BOOST_TEST_TR1_REGEX
177 namespace global_regex_namespace = ::boost;
178 #else
179 namespace global_regex_namespace = ::std::tr1;
180 #endif
181 
182 template <class Bitmask>
183 struct BitmaskConcept
184 {
constraintsboost::BitmaskConcept185    void constraints()
186    {
187       function_requires<CopyConstructibleConcept<Bitmask> >();
188       function_requires<AssignableConcept<Bitmask> >();
189 
190       m_mask1 = m_mask2 | m_mask3;
191       m_mask1 = m_mask2 & m_mask3;
192       m_mask1 = m_mask2 ^ m_mask3;
193 
194       m_mask1 = ~m_mask2;
195 
196       m_mask1 |= m_mask2;
197       m_mask1 &= m_mask2;
198       m_mask1 ^= m_mask2;
199    }
200    Bitmask m_mask1, m_mask2, m_mask3;
201 };
202 
203 template <class traits>
204 struct RegexTraitsConcept
205 {
206    RegexTraitsConcept();
207    // required typedefs:
208    typedef typename traits::char_type char_type;
209    // typedef typename traits::size_type size_type;
210    typedef typename traits::string_type string_type;
211    typedef typename traits::locale_type locale_type;
212    typedef typename traits::char_class_type char_class_type;
213 
constraintsboost::RegexTraitsConcept214    void constraints()
215    {
216       //function_requires<UnsignedIntegerConcept<size_type> >();
217       function_requires<RandomAccessContainerConcept<string_type> >();
218       function_requires<DefaultConstructibleConcept<locale_type> >();
219       function_requires<CopyConstructibleConcept<locale_type> >();
220       function_requires<AssignableConcept<locale_type> >();
221       function_requires<BitmaskConcept<char_class_type> >();
222 
223       std::size_t n = traits::length(m_pointer);
224       ignore_unused_variable_warning(n);
225 
226       char_type c = m_ctraits.translate(m_char);
227       ignore_unused_variable_warning(c);
228       c = m_ctraits.translate_nocase(m_char);
229 
230       //string_type::foobar bar;
231       string_type s1 = m_ctraits.transform(m_pointer, m_pointer);
232       ignore_unused_variable_warning(s1);
233 
234       string_type s2 = m_ctraits.transform_primary(m_pointer, m_pointer);
235       ignore_unused_variable_warning(s2);
236 
237       char_class_type cc = m_ctraits.lookup_classname(m_pointer, m_pointer);
238       ignore_unused_variable_warning(cc);
239 
240       string_type s3 = m_ctraits.lookup_collatename(m_pointer, m_pointer);
241       ignore_unused_variable_warning(s3);
242 
243       bool b = m_ctraits.isctype(m_char, cc);
244       ignore_unused_variable_warning(b);
245 
246       int v = m_ctraits.value(m_char, 16);
247       ignore_unused_variable_warning(v);
248 
249       locale_type l(m_ctraits.getloc());
250       m_traits.imbue(l);
251       ignore_unused_variable_warning(l);
252    }
253    traits m_traits;
254    const traits m_ctraits;
255    const char_type* m_pointer;
256    char_type m_char;
257 private:
258    RegexTraitsConcept& operator=(RegexTraitsConcept&);
259 };
260 
261 //
262 // helper class to compute what traits class a regular expression type is using:
263 //
264 template <class Regex>
265 struct regex_traits_computer;
266 
267 template <class charT, class traits>
268 struct regex_traits_computer< global_regex_namespace::basic_regex<charT, traits> >
269 {
270    typedef traits type;
271 };
272 
273 //
274 // BaseRegexConcept does not test anything dependent on basic_string,
275 // in case our charT does not have an associated char_traits:
276 //
277 template <class Regex>
278 struct BaseRegexConcept
279 {
280    typedef typename Regex::value_type value_type;
281    //typedef typename Regex::size_type size_type;
282    typedef typename Regex::flag_type flag_type;
283    typedef typename Regex::locale_type locale_type;
284    typedef input_iterator_archetype<value_type> input_iterator_type;
285 
286    // derived test types:
287    typedef const value_type* pointer_type;
288    typedef bidirectional_iterator_archetype<value_type> BidiIterator;
289    typedef global_regex_namespace::sub_match<BidiIterator> sub_match_type;
290    typedef global_regex_namespace::match_results<BidiIterator, allocator_architype<sub_match_type> > match_results_type;
291    typedef global_regex_namespace::match_results<BidiIterator> match_results_default_type;
292    typedef output_iterator_archetype<value_type> OutIterator;
293    typedef typename regex_traits_computer<Regex>::type traits_type;
294    typedef global_regex_namespace::regex_iterator<BidiIterator, value_type, traits_type> regex_iterator_type;
295    typedef global_regex_namespace::regex_token_iterator<BidiIterator, value_type, traits_type> regex_token_iterator_type;
296 
global_constraintsboost::BaseRegexConcept297    void global_constraints()
298    {
299       //
300       // test non-template components:
301       //
302       function_requires<BitmaskConcept<global_regex_namespace::regex_constants::syntax_option_type> >();
303       global_regex_namespace::regex_constants::syntax_option_type opts
304          = global_regex_namespace::regex_constants::icase
305          | global_regex_namespace::regex_constants::nosubs
306          | global_regex_namespace::regex_constants::optimize
307          | global_regex_namespace::regex_constants::collate
308          | global_regex_namespace::regex_constants::ECMAScript
309          | global_regex_namespace::regex_constants::basic
310          | global_regex_namespace::regex_constants::extended
311          | global_regex_namespace::regex_constants::awk
312          | global_regex_namespace::regex_constants::grep
313          | global_regex_namespace::regex_constants::egrep;
314       ignore_unused_variable_warning(opts);
315 
316       function_requires<BitmaskConcept<global_regex_namespace::regex_constants::match_flag_type> >();
317       global_regex_namespace::regex_constants::match_flag_type mopts
318          = global_regex_namespace::regex_constants::match_default
319          | global_regex_namespace::regex_constants::match_not_bol
320          | global_regex_namespace::regex_constants::match_not_eol
321          | global_regex_namespace::regex_constants::match_not_bow
322          | global_regex_namespace::regex_constants::match_not_eow
323          | global_regex_namespace::regex_constants::match_any
324          | global_regex_namespace::regex_constants::match_not_null
325          | global_regex_namespace::regex_constants::match_continuous
326          | global_regex_namespace::regex_constants::match_prev_avail
327          | global_regex_namespace::regex_constants::format_default
328          | global_regex_namespace::regex_constants::format_sed
329          | global_regex_namespace::regex_constants::format_no_copy
330          | global_regex_namespace::regex_constants::format_first_only;
331       ignore_unused_variable_warning(mopts);
332 
333       BOOST_STATIC_ASSERT((::boost::is_enum<global_regex_namespace::regex_constants::error_type>::value));
334       global_regex_namespace::regex_constants::error_type e1 = global_regex_namespace::regex_constants::error_collate;
335       ignore_unused_variable_warning(e1);
336       e1 = global_regex_namespace::regex_constants::error_ctype;
337       ignore_unused_variable_warning(e1);
338       e1 = global_regex_namespace::regex_constants::error_escape;
339       ignore_unused_variable_warning(e1);
340       e1 = global_regex_namespace::regex_constants::error_backref;
341       ignore_unused_variable_warning(e1);
342       e1 = global_regex_namespace::regex_constants::error_brack;
343       ignore_unused_variable_warning(e1);
344       e1 = global_regex_namespace::regex_constants::error_paren;
345       ignore_unused_variable_warning(e1);
346       e1 = global_regex_namespace::regex_constants::error_brace;
347       ignore_unused_variable_warning(e1);
348       e1 = global_regex_namespace::regex_constants::error_badbrace;
349       ignore_unused_variable_warning(e1);
350       e1 = global_regex_namespace::regex_constants::error_range;
351       ignore_unused_variable_warning(e1);
352       e1 = global_regex_namespace::regex_constants::error_space;
353       ignore_unused_variable_warning(e1);
354       e1 = global_regex_namespace::regex_constants::error_badrepeat;
355       ignore_unused_variable_warning(e1);
356       e1 = global_regex_namespace::regex_constants::error_complexity;
357       ignore_unused_variable_warning(e1);
358       e1 = global_regex_namespace::regex_constants::error_stack;
359       ignore_unused_variable_warning(e1);
360 
361       BOOST_STATIC_ASSERT((::boost::is_base_and_derived<std::runtime_error, global_regex_namespace::regex_error>::value  ));
362       const global_regex_namespace::regex_error except(e1);
363       e1 = except.code();
364 
365       typedef typename Regex::value_type regex_value_type;
366       function_requires< RegexTraitsConcept<global_regex_namespace::regex_traits<char> > >();
367       function_requires< BaseRegexConcept<global_regex_namespace::basic_regex<char> > >();
368    }
constraintsboost::BaseRegexConcept369    void constraints()
370    {
371       global_constraints();
372 
373       BOOST_STATIC_ASSERT((::boost::is_same< flag_type, global_regex_namespace::regex_constants::syntax_option_type>::value));
374       flag_type opts
375          = Regex::icase
376          | Regex::nosubs
377          | Regex::optimize
378          | Regex::collate
379          | Regex::ECMAScript
380          | Regex::basic
381          | Regex::extended
382          | Regex::awk
383          | Regex::grep
384          | Regex::egrep;
385       ignore_unused_variable_warning(opts);
386 
387       function_requires<DefaultConstructibleConcept<Regex> >();
388       function_requires<CopyConstructibleConcept<Regex> >();
389 
390       // Regex constructors:
391       Regex e1(m_pointer);
392       ignore_unused_variable_warning(e1);
393       Regex e2(m_pointer, m_flags);
394       ignore_unused_variable_warning(e2);
395       Regex e3(m_pointer, m_size, m_flags);
396       ignore_unused_variable_warning(e3);
397       Regex e4(in1, in2);
398       ignore_unused_variable_warning(e4);
399       Regex e5(in1, in2, m_flags);
400       ignore_unused_variable_warning(e5);
401 
402       // assign etc:
403       Regex e;
404       e = m_pointer;
405       e = e1;
406       e.assign(e1);
407       e.assign(m_pointer);
408       e.assign(m_pointer, m_flags);
409       e.assign(m_pointer, m_size, m_flags);
410       e.assign(in1, in2);
411       e.assign(in1, in2, m_flags);
412 
413       // access:
414       const Regex ce;
415       typename Regex::size_type i = ce.mark_count();
416       ignore_unused_variable_warning(i);
417       m_flags = ce.flags();
418       e.imbue(ce.getloc());
419       e.swap(e1);
420 
421       global_regex_namespace::swap(e, e1);
422 
423       // sub_match:
424       BOOST_STATIC_ASSERT((::boost::is_base_and_derived<std::pair<BidiIterator, BidiIterator>, sub_match_type>::value));
425       typedef typename sub_match_type::value_type sub_value_type;
426       typedef typename sub_match_type::difference_type sub_diff_type;
427       typedef typename sub_match_type::iterator sub_iter_type;
428       BOOST_STATIC_ASSERT((::boost::is_same<sub_value_type, value_type>::value));
429       BOOST_STATIC_ASSERT((::boost::is_same<sub_iter_type, BidiIterator>::value));
430       bool b = m_sub.matched;
431       ignore_unused_variable_warning(b);
432       BidiIterator bi = m_sub.first;
433       ignore_unused_variable_warning(bi);
434       bi = m_sub.second;
435       ignore_unused_variable_warning(bi);
436       sub_diff_type diff = m_sub.length();
437       ignore_unused_variable_warning(diff);
438       // match_results tests:
439       typedef typename match_results_type::value_type mr_value_type;
440       typedef typename match_results_type::const_reference mr_const_reference;
441       typedef typename match_results_type::reference mr_reference;
442       typedef typename match_results_type::const_iterator mr_const_iterator;
443       typedef typename match_results_type::iterator mr_iterator;
444       typedef typename match_results_type::difference_type mr_difference_type;
445       typedef typename match_results_type::size_type mr_size_type;
446       typedef typename match_results_type::allocator_type mr_allocator_type;
447       typedef typename match_results_type::char_type mr_char_type;
448       typedef typename match_results_type::string_type mr_string_type;
449 
450       match_results_type m1;
451       mr_allocator_type at;
452       match_results_type m2(at);
453       match_results_type m3(m1);
454       m1 = m2;
455 
456       int ival = 0;
457 
458       mr_size_type mrs = m_cresults.size();
459       ignore_unused_variable_warning(mrs);
460       mrs = m_cresults.max_size();
461       ignore_unused_variable_warning(mrs);
462       b = m_cresults.empty();
463       ignore_unused_variable_warning(b);
464       mr_difference_type mrd = m_cresults.length();
465       ignore_unused_variable_warning(mrd);
466       mrd = m_cresults.length(ival);
467       ignore_unused_variable_warning(mrd);
468       mrd = m_cresults.position();
469       ignore_unused_variable_warning(mrd);
470       mrd = m_cresults.position(mrs);
471       ignore_unused_variable_warning(mrd);
472 
473       mr_const_reference mrcr = m_cresults[ival];
474       ignore_unused_variable_warning(mrcr);
475       mr_const_reference mrcr2 = m_cresults.prefix();
476       ignore_unused_variable_warning(mrcr2);
477       mr_const_reference mrcr3 = m_cresults.suffix();
478       ignore_unused_variable_warning(mrcr3);
479       mr_const_iterator mrci = m_cresults.begin();
480       ignore_unused_variable_warning(mrci);
481       mrci = m_cresults.end();
482       ignore_unused_variable_warning(mrci);
483 
484       mr_allocator_type at2 = m_cresults.get_allocator();
485       m_results.swap(m_results);
486       global_regex_namespace::swap(m_results, m_results);
487 
488       // regex_match:
489       b = global_regex_namespace::regex_match(m_in, m_in, m_results, e);
490       ignore_unused_variable_warning(b);
491       b = global_regex_namespace::regex_match(m_in, m_in, m_results, e, m_mft);
492       ignore_unused_variable_warning(b);
493       b = global_regex_namespace::regex_match(m_in, m_in, e);
494       ignore_unused_variable_warning(b);
495       b = global_regex_namespace::regex_match(m_in, m_in, e, m_mft);
496       ignore_unused_variable_warning(b);
497       b = global_regex_namespace::regex_match(m_pointer, m_pmatch, e);
498       ignore_unused_variable_warning(b);
499       b = global_regex_namespace::regex_match(m_pointer, m_pmatch, e, m_mft);
500       ignore_unused_variable_warning(b);
501       b = global_regex_namespace::regex_match(m_pointer, e);
502       ignore_unused_variable_warning(b);
503       b = global_regex_namespace::regex_match(m_pointer, e, m_mft);
504       ignore_unused_variable_warning(b);
505       // regex_search:
506       b = global_regex_namespace::regex_search(m_in, m_in, m_results, e);
507       ignore_unused_variable_warning(b);
508       b = global_regex_namespace::regex_search(m_in, m_in, m_results, e, m_mft);
509       ignore_unused_variable_warning(b);
510       b = global_regex_namespace::regex_search(m_in, m_in, e);
511       ignore_unused_variable_warning(b);
512       b = global_regex_namespace::regex_search(m_in, m_in, e, m_mft);
513       ignore_unused_variable_warning(b);
514       b = global_regex_namespace::regex_search(m_pointer, m_pmatch, e);
515       ignore_unused_variable_warning(b);
516       b = global_regex_namespace::regex_search(m_pointer, m_pmatch, e, m_mft);
517       ignore_unused_variable_warning(b);
518       b = global_regex_namespace::regex_search(m_pointer, e);
519       ignore_unused_variable_warning(b);
520       b = global_regex_namespace::regex_search(m_pointer, e, m_mft);
521       ignore_unused_variable_warning(b);
522 
523       // regex_iterator:
524       typedef typename regex_iterator_type::regex_type rit_regex_type;
525       typedef typename regex_iterator_type::value_type rit_value_type;
526       typedef typename regex_iterator_type::difference_type rit_difference_type;
527       typedef typename regex_iterator_type::pointer rit_pointer;
528       typedef typename regex_iterator_type::reference rit_reference;
529       typedef typename regex_iterator_type::iterator_category rit_iterator_category;
530       BOOST_STATIC_ASSERT((::boost::is_same<rit_regex_type, Regex>::value));
531       BOOST_STATIC_ASSERT((::boost::is_same<rit_value_type, match_results_default_type>::value));
532       BOOST_STATIC_ASSERT((::boost::is_same<rit_difference_type, std::ptrdiff_t>::value));
533       BOOST_STATIC_ASSERT((::boost::is_same<rit_pointer, const match_results_default_type*>::value));
534       BOOST_STATIC_ASSERT((::boost::is_same<rit_reference, const match_results_default_type&>::value));
535       BOOST_STATIC_ASSERT((::boost::is_convertible<rit_iterator_category*, std::forward_iterator_tag*>::value));
536       // this takes care of most of the checks needed:
537       function_requires<ForwardIteratorConcept<regex_iterator_type> >();
538       regex_iterator_type iter1(m_in, m_in, e);
539       ignore_unused_variable_warning(iter1);
540       regex_iterator_type iter2(m_in, m_in, e, m_mft);
541       ignore_unused_variable_warning(iter2);
542 
543       // regex_token_iterator:
544       typedef typename regex_token_iterator_type::regex_type rtit_regex_type;
545       typedef typename regex_token_iterator_type::value_type rtit_value_type;
546       typedef typename regex_token_iterator_type::difference_type rtit_difference_type;
547       typedef typename regex_token_iterator_type::pointer rtit_pointer;
548       typedef typename regex_token_iterator_type::reference rtit_reference;
549       typedef typename regex_token_iterator_type::iterator_category rtit_iterator_category;
550       BOOST_STATIC_ASSERT((::boost::is_same<rtit_regex_type, Regex>::value));
551       BOOST_STATIC_ASSERT((::boost::is_same<rtit_value_type, sub_match_type>::value));
552       BOOST_STATIC_ASSERT((::boost::is_same<rtit_difference_type, std::ptrdiff_t>::value));
553       BOOST_STATIC_ASSERT((::boost::is_same<rtit_pointer, const sub_match_type*>::value));
554       BOOST_STATIC_ASSERT((::boost::is_same<rtit_reference, const sub_match_type&>::value));
555       BOOST_STATIC_ASSERT((::boost::is_convertible<rtit_iterator_category*, std::forward_iterator_tag*>::value));
556       // this takes care of most of the checks needed:
557       function_requires<ForwardIteratorConcept<regex_token_iterator_type> >();
558       regex_token_iterator_type ti1(m_in, m_in, e);
559       ignore_unused_variable_warning(ti1);
560       regex_token_iterator_type ti2(m_in, m_in, e, 0);
561       ignore_unused_variable_warning(ti2);
562       regex_token_iterator_type ti3(m_in, m_in, e, 0, m_mft);
563       ignore_unused_variable_warning(ti3);
564       std::vector<int> subs;
565       regex_token_iterator_type ti4(m_in, m_in, e, subs);
566       ignore_unused_variable_warning(ti4);
567       regex_token_iterator_type ti5(m_in, m_in, e, subs, m_mft);
568       ignore_unused_variable_warning(ti5);
569       static const int i_array[3] = { 1, 2, 3, };
570       regex_token_iterator_type ti6(m_in, m_in, e, i_array);
571       ignore_unused_variable_warning(ti6);
572       regex_token_iterator_type ti7(m_in, m_in, e, i_array, m_mft);
573       ignore_unused_variable_warning(ti7);
574    }
575 
576    pointer_type m_pointer;
577    flag_type m_flags;
578    std::size_t m_size;
579    input_iterator_type in1, in2;
580    const sub_match_type m_sub;
581    const value_type m_char;
582    match_results_type m_results;
583    const match_results_type m_cresults;
584    OutIterator m_out;
585    BidiIterator m_in;
586    global_regex_namespace::regex_constants::match_flag_type m_mft;
587    global_regex_namespace::match_results<
588       pointer_type,
589       allocator_architype<global_regex_namespace::sub_match<pointer_type> > >
590       m_pmatch;
591 
592    BaseRegexConcept();
593    BaseRegexConcept(const BaseRegexConcept&);
594    BaseRegexConcept& operator=(const BaseRegexConcept&);
595 };
596 
597 //
598 // RegexConcept:
599 // Test every interface in the std:
600 //
601 template <class Regex>
602 struct RegexConcept
603 {
604    typedef typename Regex::value_type value_type;
605    //typedef typename Regex::size_type size_type;
606    typedef typename Regex::flag_type flag_type;
607    typedef typename Regex::locale_type locale_type;
608 
609    // derived test types:
610    typedef const value_type* pointer_type;
611    typedef std::basic_string<value_type> string_type;
612    typedef boost::bidirectional_iterator_archetype<value_type> BidiIterator;
613    typedef global_regex_namespace::sub_match<BidiIterator> sub_match_type;
614    typedef global_regex_namespace::match_results<BidiIterator, allocator_architype<sub_match_type> > match_results_type;
615    typedef output_iterator_archetype<value_type> OutIterator;
616 
617 
constraintsboost::RegexConcept618    void constraints()
619    {
620       function_requires<BaseRegexConcept<Regex> >();
621       // string based construct:
622       Regex e1(m_string);
623       ignore_unused_variable_warning(e1);
624       Regex e2(m_string, m_flags);
625       ignore_unused_variable_warning(e2);
626 
627       // assign etc:
628       Regex e;
629       e = m_string;
630       e.assign(m_string);
631       e.assign(m_string, m_flags);
632 
633       // sub_match:
634       string_type s(m_sub);
635       ignore_unused_variable_warning(s);
636       s = m_sub.str();
637       ignore_unused_variable_warning(s);
638       int i = m_sub.compare(m_string);
639       ignore_unused_variable_warning(i);
640 
641       int i2 = m_sub.compare(m_sub);
642       ignore_unused_variable_warning(i2);
643       i2 = m_sub.compare(m_pointer);
644       ignore_unused_variable_warning(i2);
645 
646       bool b = m_sub == m_sub;
647       ignore_unused_variable_warning(b);
648       b = m_sub != m_sub;
649       ignore_unused_variable_warning(b);
650       b = m_sub <= m_sub;
651       ignore_unused_variable_warning(b);
652       b = m_sub <= m_sub;
653       ignore_unused_variable_warning(b);
654       b = m_sub > m_sub;
655       ignore_unused_variable_warning(b);
656       b = m_sub >= m_sub;
657       ignore_unused_variable_warning(b);
658 
659       b = m_sub == m_pointer;
660       ignore_unused_variable_warning(b);
661       b = m_sub != m_pointer;
662       ignore_unused_variable_warning(b);
663       b = m_sub <= m_pointer;
664       ignore_unused_variable_warning(b);
665       b = m_sub <= m_pointer;
666       ignore_unused_variable_warning(b);
667       b = m_sub > m_pointer;
668       ignore_unused_variable_warning(b);
669       b = m_sub >= m_pointer;
670       ignore_unused_variable_warning(b);
671 
672       b = m_pointer == m_sub;
673       ignore_unused_variable_warning(b);
674       b = m_pointer != m_sub;
675       ignore_unused_variable_warning(b);
676       b = m_pointer <= m_sub;
677       ignore_unused_variable_warning(b);
678       b = m_pointer <= m_sub;
679       ignore_unused_variable_warning(b);
680       b = m_pointer > m_sub;
681       ignore_unused_variable_warning(b);
682       b = m_pointer >= m_sub;
683       ignore_unused_variable_warning(b);
684 
685       b = m_sub == m_char;
686       ignore_unused_variable_warning(b);
687       b = m_sub != m_char;
688       ignore_unused_variable_warning(b);
689       b = m_sub <= m_char;
690       ignore_unused_variable_warning(b);
691       b = m_sub <= m_char;
692       ignore_unused_variable_warning(b);
693       b = m_sub > m_char;
694       ignore_unused_variable_warning(b);
695       b = m_sub >= m_char;
696       ignore_unused_variable_warning(b);
697 
698       b = m_char == m_sub;
699       ignore_unused_variable_warning(b);
700       b = m_char != m_sub;
701       ignore_unused_variable_warning(b);
702       b = m_char <= m_sub;
703       ignore_unused_variable_warning(b);
704       b = m_char <= m_sub;
705       ignore_unused_variable_warning(b);
706       b = m_char > m_sub;
707       ignore_unused_variable_warning(b);
708       b = m_char >= m_sub;
709       ignore_unused_variable_warning(b);
710 
711       b = m_sub == m_string;
712       ignore_unused_variable_warning(b);
713       b = m_sub != m_string;
714       ignore_unused_variable_warning(b);
715       b = m_sub <= m_string;
716       ignore_unused_variable_warning(b);
717       b = m_sub <= m_string;
718       ignore_unused_variable_warning(b);
719       b = m_sub > m_string;
720       ignore_unused_variable_warning(b);
721       b = m_sub >= m_string;
722       ignore_unused_variable_warning(b);
723 
724       b = m_string == m_sub;
725       ignore_unused_variable_warning(b);
726       b = m_string != m_sub;
727       ignore_unused_variable_warning(b);
728       b = m_string <= m_sub;
729       ignore_unused_variable_warning(b);
730       b = m_string <= m_sub;
731       ignore_unused_variable_warning(b);
732       b = m_string > m_sub;
733       ignore_unused_variable_warning(b);
734       b = m_string >= m_sub;
735       ignore_unused_variable_warning(b);
736 
737       // match results:
738       m_string = m_results.str();
739       ignore_unused_variable_warning(m_string);
740       m_string = m_results.str(0);
741       ignore_unused_variable_warning(m_string);
742       m_out = m_cresults.format(m_out, m_string);
743       m_out = m_cresults.format(m_out, m_string, m_mft);
744       m_string = m_cresults.format(m_string);
745       ignore_unused_variable_warning(m_string);
746       m_string = m_cresults.format(m_string, m_mft);
747       ignore_unused_variable_warning(m_string);
748 
749       // regex_match:
750       b = global_regex_namespace::regex_match(m_string, m_smatch, e);
751       ignore_unused_variable_warning(b);
752       b = global_regex_namespace::regex_match(m_string, m_smatch, e, m_mft);
753       ignore_unused_variable_warning(b);
754       b = global_regex_namespace::regex_match(m_string, e);
755       ignore_unused_variable_warning(b);
756       b = global_regex_namespace::regex_match(m_string, e, m_mft);
757       ignore_unused_variable_warning(b);
758 
759       // regex_search:
760       b = global_regex_namespace::regex_search(m_string, m_smatch, e);
761       ignore_unused_variable_warning(b);
762       b = global_regex_namespace::regex_search(m_string, m_smatch, e, m_mft);
763       ignore_unused_variable_warning(b);
764       b = global_regex_namespace::regex_search(m_string, e);
765       ignore_unused_variable_warning(b);
766       b = global_regex_namespace::regex_search(m_string, e, m_mft);
767       ignore_unused_variable_warning(b);
768 
769       // regex_replace:
770       m_out = global_regex_namespace::regex_replace(m_out, m_in, m_in, e, m_string, m_mft);
771       m_out = global_regex_namespace::regex_replace(m_out, m_in, m_in, e, m_string);
772       m_string = global_regex_namespace::regex_replace(m_string, e, m_string, m_mft);
773       ignore_unused_variable_warning(m_string);
774       m_string = global_regex_namespace::regex_replace(m_string, e, m_string);
775       ignore_unused_variable_warning(m_string);
776 
777    }
778 
779    flag_type m_flags;
780    string_type m_string;
781    const sub_match_type m_sub;
782    match_results_type m_results;
783    pointer_type m_pointer;
784    value_type m_char;
785    const match_results_type m_cresults;
786    OutIterator m_out;
787    BidiIterator m_in;
788    global_regex_namespace::regex_constants::match_flag_type m_mft;
789    global_regex_namespace::match_results<typename string_type::const_iterator, allocator_architype<global_regex_namespace::sub_match<typename string_type::const_iterator> > > m_smatch;
790 
791    RegexConcept();
792    RegexConcept(const RegexConcept&);
793    RegexConcept& operator=(const RegexConcept&);
794 };
795 
796 #ifndef BOOST_REGEX_TEST_STD
797 
798 template <class M>
799 struct functor1
800 {
801    typedef typename M::char_type char_type;
operator ()boost::functor1802    const char_type* operator()(const M&)const
803    {
804       static const char_type c = static_cast<char_type>(0);
805       return &c;
806    }
807 };
808 template <class M>
809 struct functor1b
810 {
811    typedef typename M::char_type char_type;
operator ()boost::functor1b812    std::vector<char_type> operator()(const M&)const
813    {
814       static const std::vector<char_type> c;
815       return c;
816    }
817 };
818 template <class M>
819 struct functor2
820 {
821    template <class O>
operator ()boost::functor2822    O operator()(const M& /*m*/, O i)const
823    {
824       return i;
825    }
826 };
827 template <class M>
828 struct functor3
829 {
830    template <class O>
operator ()boost::functor3831    O operator()(const M& /*m*/, O i, regex_constants::match_flag_type)const
832    {
833       return i;
834    }
835 };
836 
837 //
838 // BoostRegexConcept:
839 // Test every interface in the Boost implementation:
840 //
841 template <class Regex>
842 struct BoostRegexConcept
843 {
844    typedef typename Regex::value_type value_type;
845    typedef typename Regex::size_type size_type;
846    typedef typename Regex::flag_type flag_type;
847    typedef typename Regex::locale_type locale_type;
848 
849    // derived test types:
850    typedef const value_type* pointer_type;
851    typedef std::basic_string<value_type> string_type;
852    typedef typename Regex::const_iterator const_iterator;
853    typedef bidirectional_iterator_archetype<value_type> BidiIterator;
854    typedef output_iterator_archetype<value_type> OutputIterator;
855    typedef global_regex_namespace::sub_match<BidiIterator> sub_match_type;
856    typedef global_regex_namespace::match_results<BidiIterator, allocator_architype<sub_match_type> > match_results_type;
857    typedef global_regex_namespace::match_results<BidiIterator> match_results_default_type;
858 
constraintsboost::BoostRegexConcept859    void constraints()
860    {
861       global_regex_namespace::regex_constants::match_flag_type mopts
862          = global_regex_namespace::regex_constants::match_default
863          | global_regex_namespace::regex_constants::match_not_bol
864          | global_regex_namespace::regex_constants::match_not_eol
865          | global_regex_namespace::regex_constants::match_not_bow
866          | global_regex_namespace::regex_constants::match_not_eow
867          | global_regex_namespace::regex_constants::match_any
868          | global_regex_namespace::regex_constants::match_not_null
869          | global_regex_namespace::regex_constants::match_continuous
870          | global_regex_namespace::regex_constants::match_partial
871          | global_regex_namespace::regex_constants::match_prev_avail
872          | global_regex_namespace::regex_constants::format_default
873          | global_regex_namespace::regex_constants::format_sed
874          | global_regex_namespace::regex_constants::format_perl
875          | global_regex_namespace::regex_constants::format_no_copy
876          | global_regex_namespace::regex_constants::format_first_only;
877 
878       (void)mopts;
879 
880       function_requires<RegexConcept<Regex> >();
881       const global_regex_namespace::regex_error except(global_regex_namespace::regex_constants::error_collate);
882       std::ptrdiff_t pt = except.position();
883       ignore_unused_variable_warning(pt);
884       const Regex ce, ce2;
885 #ifndef BOOST_NO_STD_LOCALE
886       m_stream << ce;
887 #endif
888       unsigned i = ce.error_code();
889       ignore_unused_variable_warning(i);
890       pointer_type p = ce.expression();
891       ignore_unused_variable_warning(p);
892       int i2 = ce.compare(ce2);
893       ignore_unused_variable_warning(i2);
894       bool b = ce == ce2;
895       ignore_unused_variable_warning(b);
896       b = ce.empty();
897       ignore_unused_variable_warning(b);
898       b = ce != ce2;
899       ignore_unused_variable_warning(b);
900       b = ce < ce2;
901       ignore_unused_variable_warning(b);
902       b = ce > ce2;
903       ignore_unused_variable_warning(b);
904       b = ce <= ce2;
905       ignore_unused_variable_warning(b);
906       b = ce >= ce2;
907       ignore_unused_variable_warning(b);
908       i = ce.status();
909       ignore_unused_variable_warning(i);
910       size_type s = ce.max_size();
911       ignore_unused_variable_warning(s);
912       s = ce.size();
913       ignore_unused_variable_warning(s);
914       const_iterator pi = ce.begin();
915       ignore_unused_variable_warning(pi);
916       pi = ce.end();
917       ignore_unused_variable_warning(pi);
918       string_type s2 = ce.str();
919       ignore_unused_variable_warning(s2);
920 
921       m_string = m_sub + m_sub;
922       ignore_unused_variable_warning(m_string);
923       m_string = m_sub + m_pointer;
924       ignore_unused_variable_warning(m_string);
925       m_string = m_pointer + m_sub;
926       ignore_unused_variable_warning(m_string);
927       m_string = m_sub + m_string;
928       ignore_unused_variable_warning(m_string);
929       m_string = m_string + m_sub;
930       ignore_unused_variable_warning(m_string);
931       m_string = m_sub + m_char;
932       ignore_unused_variable_warning(m_string);
933       m_string = m_char + m_sub;
934       ignore_unused_variable_warning(m_string);
935 
936       // Named sub-expressions:
937       m_sub = m_cresults[&m_char];
938       ignore_unused_variable_warning(m_sub);
939       m_sub = m_cresults[m_string];
940       ignore_unused_variable_warning(m_sub);
941       m_sub = m_cresults[""];
942       ignore_unused_variable_warning(m_sub);
943       m_sub = m_cresults[std::string("")];
944       ignore_unused_variable_warning(m_sub);
945       m_string = m_cresults.str(&m_char);
946       ignore_unused_variable_warning(m_string);
947       m_string = m_cresults.str(m_string);
948       ignore_unused_variable_warning(m_string);
949       m_string = m_cresults.str("");
950       ignore_unused_variable_warning(m_string);
951       m_string = m_cresults.str(std::string(""));
952       ignore_unused_variable_warning(m_string);
953 
954       typename match_results_type::difference_type diff;
955       diff = m_cresults.length(&m_char);
956       ignore_unused_variable_warning(diff);
957       diff = m_cresults.length(m_string);
958       ignore_unused_variable_warning(diff);
959       diff = m_cresults.length("");
960       ignore_unused_variable_warning(diff);
961       diff = m_cresults.length(std::string(""));
962       ignore_unused_variable_warning(diff);
963       diff = m_cresults.position(&m_char);
964       ignore_unused_variable_warning(diff);
965       diff = m_cresults.position(m_string);
966       ignore_unused_variable_warning(diff);
967       diff = m_cresults.position("");
968       ignore_unused_variable_warning(diff);
969       diff = m_cresults.position(std::string(""));
970       ignore_unused_variable_warning(diff);
971 
972 #ifndef BOOST_NO_STD_LOCALE
973       m_stream << m_sub;
974       m_stream << m_cresults;
975 #endif
976       //
977       // Extended formatting with a functor:
978       //
979       regex_constants::match_flag_type f = regex_constants::match_default;
980       OutputIterator out = static_object<OutputIterator>::get();
981 
982       functor3<match_results_default_type> func3;
983       functor2<match_results_default_type> func2;
984       functor1<match_results_default_type> func1;
985 
986       functor3<match_results_type> func3b;
987       functor2<match_results_type> func2b;
988       functor1<match_results_type> func1b;
989 
990       out = regex_format(out, m_cresults, func3b, f);
991       out = regex_format(out, m_cresults, func3b);
992       out = regex_format(out, m_cresults, func2b, f);
993       out = regex_format(out, m_cresults, func2b);
994       out = regex_format(out, m_cresults, func1b, f);
995       out = regex_format(out, m_cresults, func1b);
996       out = regex_format(out, m_cresults, boost::ref(func3b), f);
997       out = regex_format(out, m_cresults, boost::ref(func3b));
998       out = regex_format(out, m_cresults, boost::ref(func2b), f);
999       out = regex_format(out, m_cresults, boost::ref(func2b));
1000       out = regex_format(out, m_cresults, boost::ref(func1b), f);
1001       out = regex_format(out, m_cresults, boost::ref(func1b));
1002       out = regex_format(out, m_cresults, boost::cref(func3b), f);
1003       out = regex_format(out, m_cresults, boost::cref(func3b));
1004       out = regex_format(out, m_cresults, boost::cref(func2b), f);
1005       out = regex_format(out, m_cresults, boost::cref(func2b));
1006       out = regex_format(out, m_cresults, boost::cref(func1b), f);
1007       out = regex_format(out, m_cresults, boost::cref(func1b));
1008 
1009       m_string += regex_format(m_cresults, func3b, f);
1010       m_string += regex_format(m_cresults, func3b);
1011       m_string += regex_format(m_cresults, func2b, f);
1012       m_string += regex_format(m_cresults, func2b);
1013       m_string += regex_format(m_cresults, func1b, f);
1014       m_string += regex_format(m_cresults, func1b);
1015       m_string += regex_format(m_cresults, boost::ref(func3b), f);
1016       m_string += regex_format(m_cresults, boost::ref(func3b));
1017       m_string += regex_format(m_cresults, boost::ref(func2b), f);
1018       m_string += regex_format(m_cresults, boost::ref(func2b));
1019       m_string += regex_format(m_cresults, boost::ref(func1b), f);
1020       m_string += regex_format(m_cresults, boost::ref(func1b));
1021       m_string += regex_format(m_cresults, boost::cref(func3b), f);
1022       m_string += regex_format(m_cresults, boost::cref(func3b));
1023       m_string += regex_format(m_cresults, boost::cref(func2b), f);
1024       m_string += regex_format(m_cresults, boost::cref(func2b));
1025       m_string += regex_format(m_cresults, boost::cref(func1b), f);
1026       m_string += regex_format(m_cresults, boost::cref(func1b));
1027 
1028       out = m_cresults.format(out, func3b, f);
1029       out = m_cresults.format(out, func3b);
1030       out = m_cresults.format(out, func2b, f);
1031       out = m_cresults.format(out, func2b);
1032       out = m_cresults.format(out, func1b, f);
1033       out = m_cresults.format(out, func1b);
1034       out = m_cresults.format(out, boost::ref(func3b), f);
1035       out = m_cresults.format(out, boost::ref(func3b));
1036       out = m_cresults.format(out, boost::ref(func2b), f);
1037       out = m_cresults.format(out, boost::ref(func2b));
1038       out = m_cresults.format(out, boost::ref(func1b), f);
1039       out = m_cresults.format(out, boost::ref(func1b));
1040       out = m_cresults.format(out, boost::cref(func3b), f);
1041       out = m_cresults.format(out, boost::cref(func3b));
1042       out = m_cresults.format(out, boost::cref(func2b), f);
1043       out = m_cresults.format(out, boost::cref(func2b));
1044       out = m_cresults.format(out, boost::cref(func1b), f);
1045       out = m_cresults.format(out, boost::cref(func1b));
1046 
1047       m_string += m_cresults.format(func3b, f);
1048       m_string += m_cresults.format(func3b);
1049       m_string += m_cresults.format(func2b, f);
1050       m_string += m_cresults.format(func2b);
1051       m_string += m_cresults.format(func1b, f);
1052       m_string += m_cresults.format(func1b);
1053       m_string += m_cresults.format(boost::ref(func3b), f);
1054       m_string += m_cresults.format(boost::ref(func3b));
1055       m_string += m_cresults.format(boost::ref(func2b), f);
1056       m_string += m_cresults.format(boost::ref(func2b));
1057       m_string += m_cresults.format(boost::ref(func1b), f);
1058       m_string += m_cresults.format(boost::ref(func1b));
1059       m_string += m_cresults.format(boost::cref(func3b), f);
1060       m_string += m_cresults.format(boost::cref(func3b));
1061       m_string += m_cresults.format(boost::cref(func2b), f);
1062       m_string += m_cresults.format(boost::cref(func2b));
1063       m_string += m_cresults.format(boost::cref(func1b), f);
1064       m_string += m_cresults.format(boost::cref(func1b));
1065 
1066       out = regex_replace(out, m_in, m_in, ce, func3, f);
1067       out = regex_replace(out, m_in, m_in, ce, func3);
1068       out = regex_replace(out, m_in, m_in, ce, func2, f);
1069       out = regex_replace(out, m_in, m_in, ce, func2);
1070       out = regex_replace(out, m_in, m_in, ce, func1, f);
1071       out = regex_replace(out, m_in, m_in, ce, func1);
1072       out = regex_replace(out, m_in, m_in, ce, boost::ref(func3), f);
1073       out = regex_replace(out, m_in, m_in, ce, boost::ref(func3));
1074       out = regex_replace(out, m_in, m_in, ce, boost::ref(func2), f);
1075       out = regex_replace(out, m_in, m_in, ce, boost::ref(func2));
1076       out = regex_replace(out, m_in, m_in, ce, boost::ref(func1), f);
1077       out = regex_replace(out, m_in, m_in, ce, boost::ref(func1));
1078       out = regex_replace(out, m_in, m_in, ce, boost::cref(func3), f);
1079       out = regex_replace(out, m_in, m_in, ce, boost::cref(func3));
1080       out = regex_replace(out, m_in, m_in, ce, boost::cref(func2), f);
1081       out = regex_replace(out, m_in, m_in, ce, boost::cref(func2));
1082       out = regex_replace(out, m_in, m_in, ce, boost::cref(func1), f);
1083       out = regex_replace(out, m_in, m_in, ce, boost::cref(func1));
1084 
1085       functor3<match_results<typename string_type::const_iterator> > func3s;
1086       functor2<match_results<typename string_type::const_iterator> > func2s;
1087       functor1<match_results<typename string_type::const_iterator> > func1s;
1088       m_string += regex_replace(m_string, ce, func3s, f);
1089       m_string += regex_replace(m_string, ce, func3s);
1090       m_string += regex_replace(m_string, ce, func2s, f);
1091       m_string += regex_replace(m_string, ce, func2s);
1092       m_string += regex_replace(m_string, ce, func1s, f);
1093       m_string += regex_replace(m_string, ce, func1s);
1094       m_string += regex_replace(m_string, ce, boost::ref(func3s), f);
1095       m_string += regex_replace(m_string, ce, boost::ref(func3s));
1096       m_string += regex_replace(m_string, ce, boost::ref(func2s), f);
1097       m_string += regex_replace(m_string, ce, boost::ref(func2s));
1098       m_string += regex_replace(m_string, ce, boost::ref(func1s), f);
1099       m_string += regex_replace(m_string, ce, boost::ref(func1s));
1100       m_string += regex_replace(m_string, ce, boost::cref(func3s), f);
1101       m_string += regex_replace(m_string, ce, boost::cref(func3s));
1102       m_string += regex_replace(m_string, ce, boost::cref(func2s), f);
1103       m_string += regex_replace(m_string, ce, boost::cref(func2s));
1104       m_string += regex_replace(m_string, ce, boost::cref(func1s), f);
1105       m_string += regex_replace(m_string, ce, boost::cref(func1s));
1106    }
1107 
1108    std::basic_ostream<value_type> m_stream;
1109    sub_match_type m_sub;
1110    pointer_type m_pointer;
1111    string_type m_string;
1112    const value_type m_char;
1113    match_results_type m_results;
1114    const match_results_type m_cresults;
1115    BidiIterator m_in;
1116 
1117    BoostRegexConcept();
1118    BoostRegexConcept(const BoostRegexConcept&);
1119    BoostRegexConcept& operator=(const BoostRegexConcept&);
1120 };
1121 
1122 #endif // BOOST_REGEX_TEST_STD
1123 
1124 }
1125 
1126 #endif
1127