sl@0: /*
sl@0:  *
sl@0:  * Copyright (c) 2004
sl@0:  * John Maddock
sl@0:  *
sl@0:  * Use, modification and distribution are subject to the 
sl@0:  * Boost Software License, Version 1.0. (See accompanying file 
sl@0:  * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
sl@0:  *
sl@0:  */
sl@0:  
sl@0:  /*
sl@0:   *   LOCATION:    see http://www.boost.org for most recent version.
sl@0:   *   FILE         concepts.hpp
sl@0:   *   VERSION      see <boost/version.hpp>
sl@0:   *   DESCRIPTION: Declares regular expression concepts.
sl@0:   */
sl@0: 
sl@0: #ifndef BOOST_REGEX_CONCEPTS_HPP_INCLUDED
sl@0: #define BOOST_REGEX_CONCEPTS_HPP_INCLUDED
sl@0: 
sl@0: #include <boost/concept_archetype.hpp>
sl@0: #include <boost/concept_check.hpp>
sl@0: #include <boost/type_traits/is_enum.hpp>
sl@0: #include <boost/type_traits/is_base_and_derived.hpp>
sl@0: #include <boost/static_assert.hpp>
sl@0: #ifndef BOOST_TEST_TR1_REGEX
sl@0: #include <boost/regex.hpp>
sl@0: #endif
sl@0: #include <bitset>
sl@0: #include <vector>
sl@0: #include <iostream>
sl@0: 
sl@0: namespace boost{
sl@0: 
sl@0: //
sl@0: // bitmask_archetype:
sl@0: // this can be either an integer type, an enum, or a std::bitset,
sl@0: // we use the latter as the architype as it offers the "strictest"
sl@0: // of the possible interfaces:
sl@0: //
sl@0: typedef std::bitset<512> bitmask_archetype;
sl@0: //
sl@0: // char_architype:
sl@0: // A strict model for the character type interface.
sl@0: //
sl@0: struct char_architype
sl@0: {
sl@0:    // default constructable:
sl@0:    char_architype();
sl@0:    // copy constructable / assignable:
sl@0:    char_architype(const char_architype&);
sl@0:    char_architype& operator=(const char_architype&);
sl@0:    // constructable from an integral value:
sl@0:    char_architype(unsigned long val);
sl@0:    // comparable:
sl@0:    bool operator==(const char_architype&)const;
sl@0:    bool operator!=(const char_architype&)const;
sl@0:    bool operator<(const char_architype&)const;
sl@0:    bool operator<=(const char_architype&)const;
sl@0:    bool operator>=(const char_architype&)const;
sl@0:    bool operator>(const char_architype&)const;
sl@0:    // conversion to integral type:
sl@0:    operator long()const;
sl@0: };
sl@0: //
sl@0: // char_architype can not be used with basic_string:
sl@0: //
sl@0: } // namespace boost
sl@0: namespace std{
sl@0:    template<> struct char_traits<boost::char_architype>
sl@0:    {
sl@0:       // The intent is that this template is not instantiated,
sl@0:       // but this typedef gives us a chance of compilation in
sl@0:       // case it is:
sl@0:       typedef boost::char_architype char_type;
sl@0:    };
sl@0: }
sl@0: namespace boost{
sl@0: //
sl@0: // regex_traits_architype:
sl@0: // A strict interpretation of the regular expression traits class requirements.
sl@0: //
sl@0: template <class charT>
sl@0: struct regex_traits_architype
sl@0: {
sl@0: public:
sl@0:    regex_traits_architype();
sl@0:    typedef charT char_type;
sl@0:    typedef std::size_t size_type;
sl@0:    typedef std::vector<char_type> string_type;
sl@0:    typedef copy_constructible_archetype<assignable_archetype<> > locale_type;
sl@0:    typedef bitmask_archetype char_class_type;
sl@0: 
sl@0:    static size_type length(const char_type* ) { return 0; }
sl@0: 
sl@0:    charT translate(charT ) const { return charT(); }
sl@0:    charT translate_nocase(charT ) const { return static_object<charT>::get(); }
sl@0: 
sl@0:    template <class ForwardIterator>
sl@0:    string_type transform(ForwardIterator , ForwardIterator ) const
sl@0:    { return static_object<string_type>::get(); }
sl@0:    template <class ForwardIterator>
sl@0:    string_type transform_primary(ForwardIterator , ForwardIterator ) const
sl@0:    { return static_object<string_type>::get(); }
sl@0: 
sl@0:    template <class ForwardIterator>
sl@0:    char_class_type lookup_classname(ForwardIterator , ForwardIterator ) const
sl@0:    { return static_object<char_class_type>::get(); }
sl@0:    template <class ForwardIterator>
sl@0:    string_type lookup_collatename(ForwardIterator , ForwardIterator ) const
sl@0:    { return static_object<string_type>::get(); }
sl@0: 
sl@0:    bool isctype(charT, char_class_type) const
sl@0:    { return false; }
sl@0:    int value(charT, int) const
sl@0:    { return 0; }
sl@0: 
sl@0:    locale_type imbue(locale_type l)
sl@0:    { return l; }
sl@0:    locale_type getloc()const
sl@0:    { return static_object<locale_type>::get(); }
sl@0: 
sl@0: private:
sl@0:    // this type is not copyable:
sl@0:    regex_traits_architype(const regex_traits_architype&);
sl@0:    regex_traits_architype& operator=(const regex_traits_architype&);
sl@0: };
sl@0: 
sl@0: //
sl@0: // alter this to std::tr1, to test a std implementation:
sl@0: //
sl@0: #ifndef BOOST_TEST_TR1_REGEX
sl@0: namespace global_regex_namespace = ::boost;
sl@0: #else
sl@0: namespace global_regex_namespace = ::std::tr1;
sl@0: #endif
sl@0: 
sl@0: template <class Bitmask>
sl@0: struct BitmaskConcept
sl@0: {
sl@0:    void constraints() 
sl@0:    {
sl@0:       function_requires<CopyConstructibleConcept<Bitmask> >();
sl@0:       function_requires<AssignableConcept<Bitmask> >();
sl@0: 
sl@0:       m_mask1 = m_mask2 | m_mask3;
sl@0:       m_mask1 = m_mask2 & m_mask3;
sl@0:       m_mask1 = m_mask2 ^ m_mask3;
sl@0: 
sl@0:       m_mask1 = ~m_mask2;
sl@0: 
sl@0:       m_mask1 |= m_mask2;
sl@0:       m_mask1 &= m_mask2;
sl@0:       m_mask1 ^= m_mask2;
sl@0:    }
sl@0:    Bitmask m_mask1, m_mask2, m_mask3;
sl@0: };
sl@0: 
sl@0: template <class traits>
sl@0: struct RegexTraitsConcept
sl@0: {
sl@0:    RegexTraitsConcept();
sl@0:    // required typedefs:
sl@0:    typedef typename traits::char_type char_type;
sl@0:    typedef typename traits::size_type size_type;
sl@0:    typedef typename traits::string_type string_type;
sl@0:    typedef typename traits::locale_type locale_type;
sl@0:    typedef typename traits::char_class_type char_class_type;
sl@0: 
sl@0:    void constraints() 
sl@0:    {
sl@0:       function_requires<UnsignedIntegerConcept<size_type> >();
sl@0:       function_requires<RandomAccessContainerConcept<string_type> >();
sl@0:       function_requires<DefaultConstructibleConcept<locale_type> >();
sl@0:       function_requires<CopyConstructibleConcept<locale_type> >();
sl@0:       function_requires<AssignableConcept<locale_type> >();
sl@0:       function_requires<BitmaskConcept<char_class_type> >();
sl@0: 
sl@0:       size_type n = traits::length(m_pointer);
sl@0:       ignore_unused_variable_warning(n);
sl@0: 
sl@0:       char_type c = m_ctraits.translate(m_char);
sl@0:       ignore_unused_variable_warning(c);
sl@0:       c = m_ctraits.translate_nocase(m_char);
sl@0:       
sl@0:       //string_type::foobar bar;
sl@0:       string_type s1 = m_ctraits.transform(m_pointer, m_pointer);
sl@0:       ignore_unused_variable_warning(s1);
sl@0: 
sl@0:       string_type s2 = m_ctraits.transform_primary(m_pointer, m_pointer);
sl@0:       ignore_unused_variable_warning(s2);
sl@0: 
sl@0:       char_class_type cc = m_ctraits.lookup_classname(m_pointer, m_pointer);
sl@0:       ignore_unused_variable_warning(cc);
sl@0: 
sl@0:       string_type s3 = m_ctraits.lookup_collatename(m_pointer, m_pointer);
sl@0:       ignore_unused_variable_warning(s3);
sl@0: 
sl@0:       bool b = m_ctraits.isctype(m_char, cc);
sl@0:       ignore_unused_variable_warning(b);
sl@0: 
sl@0:       int v = m_ctraits.value(m_char, 16);
sl@0:       ignore_unused_variable_warning(v);
sl@0: 
sl@0:       locale_type l(m_ctraits.getloc());
sl@0:       m_traits.imbue(l);
sl@0:       ignore_unused_variable_warning(l);
sl@0:    }
sl@0:    traits m_traits;
sl@0:    const traits m_ctraits;
sl@0:    const char_type* m_pointer;
sl@0:    char_type m_char;
sl@0: private:
sl@0:    RegexTraitsConcept& operator=(RegexTraitsConcept&);
sl@0: };
sl@0: 
sl@0: //
sl@0: // helper class to compute what traits class a regular expression type is using:
sl@0: //
sl@0: template <class Regex>
sl@0: struct regex_traits_computer;
sl@0: 
sl@0: template <class charT, class traits>
sl@0: struct regex_traits_computer< global_regex_namespace::basic_regex<charT, traits> >
sl@0: {
sl@0:    typedef traits type;
sl@0: };
sl@0: 
sl@0: //
sl@0: // BaseRegexConcept does not test anything dependent on basic_string,
sl@0: // in case our charT does not have an associated char_traits:
sl@0: //
sl@0: template <class Regex>
sl@0: struct BaseRegexConcept
sl@0: {
sl@0:    typedef typename Regex::value_type value_type;
sl@0:    typedef typename Regex::size_type size_type;
sl@0:    typedef typename Regex::flag_type flag_type;
sl@0:    typedef typename Regex::locale_type locale_type;
sl@0:    typedef input_iterator_archetype<value_type> input_iterator_type;
sl@0: 
sl@0:    // derived test types:
sl@0:    typedef const value_type* pointer_type;
sl@0:    typedef bidirectional_iterator_archetype<value_type> BidiIterator;
sl@0:    typedef global_regex_namespace::sub_match<BidiIterator> sub_match_type;
sl@0:    typedef global_regex_namespace::match_results<BidiIterator> match_results_type;
sl@0:    typedef output_iterator_archetype<value_type> OutIterator;
sl@0:    typedef typename regex_traits_computer<Regex>::type traits_type;
sl@0:    typedef global_regex_namespace::regex_iterator<BidiIterator, value_type, traits_type> regex_iterator_type;
sl@0:    typedef global_regex_namespace::regex_token_iterator<BidiIterator, value_type, traits_type> regex_token_iterator_type;
sl@0: 
sl@0:    void global_constraints()
sl@0:    {
sl@0:       //
sl@0:       // test non-template components:
sl@0:       //
sl@0:       function_requires<BitmaskConcept<global_regex_namespace::regex_constants::syntax_option_type> >();
sl@0:       global_regex_namespace::regex_constants::syntax_option_type opts
sl@0:          = global_regex_namespace::regex_constants::icase
sl@0:          | global_regex_namespace::regex_constants::nosubs
sl@0:          | global_regex_namespace::regex_constants::optimize
sl@0:          | global_regex_namespace::regex_constants::collate
sl@0:          | global_regex_namespace::regex_constants::ECMAScript
sl@0:          | global_regex_namespace::regex_constants::basic
sl@0:          | global_regex_namespace::regex_constants::extended
sl@0:          | global_regex_namespace::regex_constants::awk
sl@0:          | global_regex_namespace::regex_constants::grep
sl@0:          | global_regex_namespace::regex_constants::egrep;
sl@0:       ignore_unused_variable_warning(opts);
sl@0: 
sl@0:       function_requires<BitmaskConcept<global_regex_namespace::regex_constants::match_flag_type> >();
sl@0:       global_regex_namespace::regex_constants::match_flag_type mopts
sl@0:          = global_regex_namespace::regex_constants::match_default
sl@0:          | global_regex_namespace::regex_constants::match_not_bol
sl@0:          | global_regex_namespace::regex_constants::match_not_eol
sl@0:          | global_regex_namespace::regex_constants::match_not_bow
sl@0:          | global_regex_namespace::regex_constants::match_not_eow
sl@0:          | global_regex_namespace::regex_constants::match_any
sl@0:          | global_regex_namespace::regex_constants::match_not_null
sl@0:          | global_regex_namespace::regex_constants::match_continuous
sl@0:          | global_regex_namespace::regex_constants::match_prev_avail
sl@0:          | global_regex_namespace::regex_constants::format_default
sl@0:          | global_regex_namespace::regex_constants::format_sed
sl@0:          | global_regex_namespace::regex_constants::format_no_copy
sl@0:          | global_regex_namespace::regex_constants::format_first_only;
sl@0:       ignore_unused_variable_warning(mopts);
sl@0: 
sl@0:       BOOST_STATIC_ASSERT((::boost::is_enum<global_regex_namespace::regex_constants::error_type>::value));
sl@0:       global_regex_namespace::regex_constants::error_type e1 = global_regex_namespace::regex_constants::error_collate;
sl@0:       ignore_unused_variable_warning(e1);
sl@0:       e1 = global_regex_namespace::regex_constants::error_ctype;
sl@0:       ignore_unused_variable_warning(e1);
sl@0:       e1 = global_regex_namespace::regex_constants::error_escape;
sl@0:       ignore_unused_variable_warning(e1);
sl@0:       e1 = global_regex_namespace::regex_constants::error_backref;
sl@0:       ignore_unused_variable_warning(e1);
sl@0:       e1 = global_regex_namespace::regex_constants::error_brack;
sl@0:       ignore_unused_variable_warning(e1);
sl@0:       e1 = global_regex_namespace::regex_constants::error_paren;
sl@0:       ignore_unused_variable_warning(e1);
sl@0:       e1 = global_regex_namespace::regex_constants::error_brace;
sl@0:       ignore_unused_variable_warning(e1);
sl@0:       e1 = global_regex_namespace::regex_constants::error_badbrace;
sl@0:       ignore_unused_variable_warning(e1);
sl@0:       e1 = global_regex_namespace::regex_constants::error_range;
sl@0:       ignore_unused_variable_warning(e1);
sl@0:       e1 = global_regex_namespace::regex_constants::error_space;
sl@0:       ignore_unused_variable_warning(e1);
sl@0:       e1 = global_regex_namespace::regex_constants::error_badrepeat;
sl@0:       ignore_unused_variable_warning(e1);
sl@0:       e1 = global_regex_namespace::regex_constants::error_complexity;
sl@0:       ignore_unused_variable_warning(e1);
sl@0:       e1 = global_regex_namespace::regex_constants::error_stack;
sl@0:       ignore_unused_variable_warning(e1);
sl@0: 
sl@0:       BOOST_STATIC_ASSERT((::boost::is_base_and_derived<std::runtime_error, global_regex_namespace::regex_error>::value  ));
sl@0:       const global_regex_namespace::regex_error except(e1);
sl@0:       e1 = except.code();
sl@0: 
sl@0:       typedef typename Regex::value_type value_type;
sl@0:       function_requires< RegexTraitsConcept<global_regex_namespace::regex_traits<char> > >();
sl@0:       function_requires< BaseRegexConcept<global_regex_namespace::basic_regex<char> > >();
sl@0:    }
sl@0:    void constraints() 
sl@0:    {
sl@0:       global_constraints();
sl@0: 
sl@0:       BOOST_STATIC_ASSERT((::boost::is_same< flag_type, global_regex_namespace::regex_constants::syntax_option_type>::value));
sl@0:       flag_type opts
sl@0:          = Regex::icase
sl@0:          | Regex::nosubs
sl@0:          | Regex::optimize
sl@0:          | Regex::collate
sl@0:          | Regex::ECMAScript
sl@0:          | Regex::basic
sl@0:          | Regex::extended
sl@0:          | Regex::awk
sl@0:          | Regex::grep
sl@0:          | Regex::egrep;
sl@0:       ignore_unused_variable_warning(opts);
sl@0: 
sl@0:       function_requires<DefaultConstructibleConcept<Regex> >();
sl@0:       function_requires<CopyConstructibleConcept<Regex> >();
sl@0: 
sl@0:       // Regex constructors:
sl@0:       Regex e1(m_pointer);
sl@0:       ignore_unused_variable_warning(e1);
sl@0:       Regex e2(m_pointer, m_flags);
sl@0:       ignore_unused_variable_warning(e2);
sl@0:       Regex e3(m_pointer, m_size, m_flags);
sl@0:       ignore_unused_variable_warning(e3);
sl@0:       Regex e4(in1, in2);
sl@0:       ignore_unused_variable_warning(e4);
sl@0:       Regex e5(in1, in2, m_flags);
sl@0:       ignore_unused_variable_warning(e5);
sl@0: 
sl@0:       // assign etc:
sl@0:       Regex e;
sl@0:       e = m_pointer;
sl@0:       e = e1;
sl@0:       e.assign(e1);
sl@0:       e.assign(m_pointer);
sl@0:       e.assign(m_pointer, m_flags);
sl@0:       e.assign(m_pointer, m_size, m_flags);
sl@0:       e.assign(in1, in2);
sl@0:       e.assign(in1, in2, m_flags);
sl@0: 
sl@0:       // access:
sl@0:       const Regex ce;
sl@0:       bool b = ce.empty();
sl@0:       ignore_unused_variable_warning(b);
sl@0:       size_type i = ce.mark_count();
sl@0:       ignore_unused_variable_warning(i);
sl@0:       m_flags = ce.flags();
sl@0:       e.imbue(ce.getloc());
sl@0:       e.swap(e1);
sl@0:       
sl@0:       global_regex_namespace::swap(e, e1);
sl@0: 
sl@0:       // sub_match:
sl@0:       BOOST_STATIC_ASSERT((::boost::is_base_and_derived<std::pair<BidiIterator, BidiIterator>, sub_match_type>::value));
sl@0:       typedef typename sub_match_type::value_type sub_value_type;
sl@0:       typedef typename sub_match_type::difference_type sub_diff_type;
sl@0:       typedef typename sub_match_type::iterator sub_iter_type;
sl@0:       BOOST_STATIC_ASSERT((::boost::is_same<sub_value_type, value_type>::value));
sl@0:       BOOST_STATIC_ASSERT((::boost::is_same<sub_iter_type, BidiIterator>::value));
sl@0:       b = m_sub.matched;
sl@0:       ignore_unused_variable_warning(b);
sl@0:       BidiIterator bi = m_sub.first;
sl@0:       ignore_unused_variable_warning(bi);
sl@0:       bi = m_sub.second;
sl@0:       ignore_unused_variable_warning(bi);
sl@0:       sub_diff_type diff = m_sub.length();
sl@0:       ignore_unused_variable_warning(diff);
sl@0:       // match_results tests:
sl@0:       typedef typename match_results_type::value_type mr_value_type;
sl@0:       typedef typename match_results_type::const_reference mr_const_reference;
sl@0:       typedef typename match_results_type::reference mr_reference;
sl@0:       typedef typename match_results_type::const_iterator mr_const_iterator;
sl@0:       typedef typename match_results_type::iterator mr_iterator;
sl@0:       typedef typename match_results_type::difference_type mr_difference_type;
sl@0:       typedef typename match_results_type::size_type mr_size_type;
sl@0:       typedef typename match_results_type::allocator_type mr_allocator_type;
sl@0:       typedef typename match_results_type::char_type mr_char_type;
sl@0:       typedef typename match_results_type::string_type mr_string_type;
sl@0: 
sl@0:       match_results_type m1;
sl@0:       mr_allocator_type at;
sl@0:       match_results_type m2(at);
sl@0:       match_results_type m3(m1);
sl@0:       m1 = m2;
sl@0: 
sl@0:       int ival = 0;
sl@0: 
sl@0:       mr_size_type mrs = m_cresults.size();
sl@0:       ignore_unused_variable_warning(mrs);
sl@0:       mrs = m_cresults.max_size();
sl@0:       ignore_unused_variable_warning(mrs);
sl@0:       b = m_cresults.empty();
sl@0:       ignore_unused_variable_warning(b);
sl@0:       mr_difference_type mrd = m_cresults.length();
sl@0:       ignore_unused_variable_warning(mrd);
sl@0:       mrd = m_cresults.length(ival);
sl@0:       ignore_unused_variable_warning(mrd);
sl@0:       mrd = m_cresults.position();
sl@0:       ignore_unused_variable_warning(mrd);
sl@0:       mrd = m_cresults.position(mrs);
sl@0:       ignore_unused_variable_warning(mrd);
sl@0: 
sl@0:       mr_const_reference mrcr = m_cresults[ival];
sl@0:       ignore_unused_variable_warning(mrcr);
sl@0:       mr_const_reference mrcr2 = m_cresults.prefix();
sl@0:       ignore_unused_variable_warning(mrcr2);
sl@0:       mr_const_reference mrcr3 = m_cresults.suffix();
sl@0:       ignore_unused_variable_warning(mrcr3);
sl@0:       mr_const_iterator mrci = m_cresults.begin();
sl@0:       ignore_unused_variable_warning(mrci);
sl@0:       mrci = m_cresults.end();
sl@0:       ignore_unused_variable_warning(mrci);
sl@0: 
sl@0:       mr_allocator_type at2 = m_cresults.get_allocator();
sl@0:       m_results.swap(m_results);
sl@0:       global_regex_namespace::swap(m_results, m_results);
sl@0: 
sl@0:       // regex_match:
sl@0:       b = global_regex_namespace::regex_match(m_in, m_in, m_results, e);
sl@0:       ignore_unused_variable_warning(b);
sl@0:       b = global_regex_namespace::regex_match(m_in, m_in, m_results, e, m_mft);
sl@0:       ignore_unused_variable_warning(b);
sl@0:       b = global_regex_namespace::regex_match(m_in, m_in, e);
sl@0:       ignore_unused_variable_warning(b);
sl@0:       b = global_regex_namespace::regex_match(m_in, m_in, e, m_mft);
sl@0:       ignore_unused_variable_warning(b);
sl@0:       b = global_regex_namespace::regex_match(m_pointer, m_pmatch, e);
sl@0:       ignore_unused_variable_warning(b);
sl@0:       b = global_regex_namespace::regex_match(m_pointer, m_pmatch, e, m_mft);
sl@0:       ignore_unused_variable_warning(b);
sl@0:       b = global_regex_namespace::regex_match(m_pointer, e);
sl@0:       ignore_unused_variable_warning(b);
sl@0:       b = global_regex_namespace::regex_match(m_pointer, e, m_mft);
sl@0:       ignore_unused_variable_warning(b);
sl@0:       // regex_search:
sl@0:       b = global_regex_namespace::regex_search(m_in, m_in, m_results, e);
sl@0:       ignore_unused_variable_warning(b);
sl@0:       b = global_regex_namespace::regex_search(m_in, m_in, m_results, e, m_mft);
sl@0:       ignore_unused_variable_warning(b);
sl@0:       b = global_regex_namespace::regex_search(m_in, m_in, e);
sl@0:       ignore_unused_variable_warning(b);
sl@0:       b = global_regex_namespace::regex_search(m_in, m_in, e, m_mft);
sl@0:       ignore_unused_variable_warning(b);
sl@0:       b = global_regex_namespace::regex_search(m_pointer, m_pmatch, e);
sl@0:       ignore_unused_variable_warning(b);
sl@0:       b = global_regex_namespace::regex_search(m_pointer, m_pmatch, e, m_mft);
sl@0:       ignore_unused_variable_warning(b);
sl@0:       b = global_regex_namespace::regex_search(m_pointer, e);
sl@0:       ignore_unused_variable_warning(b);
sl@0:       b = global_regex_namespace::regex_search(m_pointer, e, m_mft);
sl@0:       ignore_unused_variable_warning(b);
sl@0: 
sl@0:       // regex_iterator:
sl@0:       typedef typename regex_iterator_type::regex_type rit_regex_type;
sl@0:       typedef typename regex_iterator_type::value_type rit_value_type;
sl@0:       typedef typename regex_iterator_type::difference_type rit_difference_type;
sl@0:       typedef typename regex_iterator_type::pointer rit_pointer;
sl@0:       typedef typename regex_iterator_type::reference rit_reference;
sl@0:       typedef typename regex_iterator_type::iterator_category rit_iterator_category;
sl@0:       BOOST_STATIC_ASSERT((::boost::is_same<rit_regex_type, Regex>::value));
sl@0:       BOOST_STATIC_ASSERT((::boost::is_same<rit_value_type, match_results_type>::value));
sl@0:       BOOST_STATIC_ASSERT((::boost::is_same<rit_difference_type, std::ptrdiff_t>::value));
sl@0:       BOOST_STATIC_ASSERT((::boost::is_same<rit_pointer, const match_results_type*>::value));
sl@0:       BOOST_STATIC_ASSERT((::boost::is_same<rit_reference, const match_results_type&>::value));
sl@0:       BOOST_STATIC_ASSERT((::boost::is_convertible<rit_iterator_category*, std::forward_iterator_tag*>::value));
sl@0:       // this takes care of most of the checks needed:
sl@0:       function_requires<ForwardIteratorConcept<regex_iterator_type> >();
sl@0:       regex_iterator_type iter1(m_in, m_in, e);
sl@0:       ignore_unused_variable_warning(iter1);
sl@0:       regex_iterator_type iter2(m_in, m_in, e, m_mft);
sl@0:       ignore_unused_variable_warning(iter2);
sl@0: 
sl@0:       // regex_token_iterator:
sl@0:       typedef typename regex_token_iterator_type::regex_type rtit_regex_type;
sl@0:       typedef typename regex_token_iterator_type::value_type rtit_value_type;
sl@0:       typedef typename regex_token_iterator_type::difference_type rtit_difference_type;
sl@0:       typedef typename regex_token_iterator_type::pointer rtit_pointer;
sl@0:       typedef typename regex_token_iterator_type::reference rtit_reference;
sl@0:       typedef typename regex_token_iterator_type::iterator_category rtit_iterator_category;
sl@0:       BOOST_STATIC_ASSERT((::boost::is_same<rtit_regex_type, Regex>::value));
sl@0:       BOOST_STATIC_ASSERT((::boost::is_same<rtit_value_type, sub_match_type>::value));
sl@0:       BOOST_STATIC_ASSERT((::boost::is_same<rtit_difference_type, std::ptrdiff_t>::value));
sl@0:       BOOST_STATIC_ASSERT((::boost::is_same<rtit_pointer, const sub_match_type*>::value));
sl@0:       BOOST_STATIC_ASSERT((::boost::is_same<rtit_reference, const sub_match_type&>::value));
sl@0:       BOOST_STATIC_ASSERT((::boost::is_convertible<rtit_iterator_category*, std::forward_iterator_tag*>::value));
sl@0:       // this takes care of most of the checks needed:
sl@0:       function_requires<ForwardIteratorConcept<regex_token_iterator_type> >();
sl@0:       regex_token_iterator_type ti1(m_in, m_in, e);
sl@0:       ignore_unused_variable_warning(ti1);
sl@0:       regex_token_iterator_type ti2(m_in, m_in, e, 0);
sl@0:       ignore_unused_variable_warning(ti2);
sl@0:       regex_token_iterator_type ti3(m_in, m_in, e, 0, m_mft);
sl@0:       ignore_unused_variable_warning(ti3);
sl@0:       std::vector<int> subs;
sl@0:       regex_token_iterator_type ti4(m_in, m_in, e, subs);
sl@0:       ignore_unused_variable_warning(ti4);
sl@0:       regex_token_iterator_type ti5(m_in, m_in, e, subs, m_mft);
sl@0:       ignore_unused_variable_warning(ti5);
sl@0:       static const int i_array[3] = { 1, 2, 3, };
sl@0:       regex_token_iterator_type ti6(m_in, m_in, e, i_array);
sl@0:       ignore_unused_variable_warning(ti6);
sl@0:       regex_token_iterator_type ti7(m_in, m_in, e, i_array, m_mft);
sl@0:       ignore_unused_variable_warning(ti7);
sl@0:    }
sl@0: 
sl@0:    pointer_type m_pointer;
sl@0:    flag_type m_flags;
sl@0:    size_type m_size;
sl@0:    input_iterator_type in1, in2;
sl@0:    const sub_match_type m_sub;
sl@0:    const value_type m_char;
sl@0:    match_results_type m_results;
sl@0:    const match_results_type m_cresults;
sl@0:    OutIterator m_out;
sl@0:    BidiIterator m_in;
sl@0:    global_regex_namespace::regex_constants::match_flag_type m_mft;
sl@0:    global_regex_namespace::match_results<pointer_type> m_pmatch;
sl@0: 
sl@0:    BaseRegexConcept();
sl@0:    BaseRegexConcept(const BaseRegexConcept&);
sl@0:    BaseRegexConcept& operator=(const BaseRegexConcept&);
sl@0: };
sl@0: 
sl@0: //
sl@0: // RegexConcept:
sl@0: // Test every interface in the std:
sl@0: //
sl@0: template <class Regex>
sl@0: struct RegexConcept
sl@0: {
sl@0:    typedef typename Regex::value_type value_type;
sl@0:    typedef typename Regex::size_type size_type;
sl@0:    typedef typename Regex::flag_type flag_type;
sl@0:    typedef typename Regex::locale_type locale_type;
sl@0: 
sl@0:    // derived test types:
sl@0:    typedef const value_type* pointer_type;
sl@0:    typedef std::basic_string<value_type> string_type;
sl@0:    typedef boost::bidirectional_iterator_archetype<value_type> BidiIterator;
sl@0:    typedef global_regex_namespace::sub_match<BidiIterator> sub_match_type;
sl@0:    typedef global_regex_namespace::match_results<BidiIterator> match_results_type;
sl@0:    typedef output_iterator_archetype<value_type> OutIterator;
sl@0: 
sl@0: 
sl@0:    void constraints() 
sl@0:    {
sl@0:       function_requires<BaseRegexConcept<Regex> >();
sl@0:       // string based construct:
sl@0:       Regex e1(m_string);
sl@0:       ignore_unused_variable_warning(e1);
sl@0:       Regex e2(m_string, m_flags);
sl@0:       ignore_unused_variable_warning(e2);
sl@0: 
sl@0:       // assign etc:
sl@0:       Regex e;
sl@0:       e = m_string;
sl@0:       e.assign(m_string);
sl@0:       e.assign(m_string, m_flags);
sl@0: 
sl@0:       // sub_match:
sl@0:       string_type s(m_sub);
sl@0:       ignore_unused_variable_warning(s);
sl@0:       s = m_sub.str();
sl@0:       ignore_unused_variable_warning(s);
sl@0:       int i = m_sub.compare(m_string);
sl@0:       ignore_unused_variable_warning(i);
sl@0: 
sl@0:       int i2 = m_sub.compare(m_sub);
sl@0:       ignore_unused_variable_warning(i2);
sl@0:       i2 = m_sub.compare(m_pointer);
sl@0:       ignore_unused_variable_warning(i2);
sl@0: 
sl@0:       bool b = m_sub == m_sub;
sl@0:       ignore_unused_variable_warning(b);
sl@0:       b = m_sub != m_sub;
sl@0:       ignore_unused_variable_warning(b);
sl@0:       b = m_sub <= m_sub;
sl@0:       ignore_unused_variable_warning(b);
sl@0:       b = m_sub <= m_sub;
sl@0:       ignore_unused_variable_warning(b);
sl@0:       b = m_sub > m_sub;
sl@0:       ignore_unused_variable_warning(b);
sl@0:       b = m_sub >= m_sub;
sl@0:       ignore_unused_variable_warning(b);
sl@0: 
sl@0:       b = m_sub == m_pointer;
sl@0:       ignore_unused_variable_warning(b);
sl@0:       b = m_sub != m_pointer;
sl@0:       ignore_unused_variable_warning(b);
sl@0:       b = m_sub <= m_pointer;
sl@0:       ignore_unused_variable_warning(b);
sl@0:       b = m_sub <= m_pointer;
sl@0:       ignore_unused_variable_warning(b);
sl@0:       b = m_sub > m_pointer;
sl@0:       ignore_unused_variable_warning(b);
sl@0:       b = m_sub >= m_pointer;
sl@0:       ignore_unused_variable_warning(b);
sl@0: 
sl@0:       b = m_pointer == m_sub;
sl@0:       ignore_unused_variable_warning(b);
sl@0:       b = m_pointer != m_sub;
sl@0:       ignore_unused_variable_warning(b);
sl@0:       b = m_pointer <= m_sub;
sl@0:       ignore_unused_variable_warning(b);
sl@0:       b = m_pointer <= m_sub;
sl@0:       ignore_unused_variable_warning(b);
sl@0:       b = m_pointer > m_sub;
sl@0:       ignore_unused_variable_warning(b);
sl@0:       b = m_pointer >= m_sub;
sl@0:       ignore_unused_variable_warning(b);
sl@0: 
sl@0:       b = m_sub == m_char;
sl@0:       ignore_unused_variable_warning(b);
sl@0:       b = m_sub != m_char;
sl@0:       ignore_unused_variable_warning(b);
sl@0:       b = m_sub <= m_char;
sl@0:       ignore_unused_variable_warning(b);
sl@0:       b = m_sub <= m_char;
sl@0:       ignore_unused_variable_warning(b);
sl@0:       b = m_sub > m_char;
sl@0:       ignore_unused_variable_warning(b);
sl@0:       b = m_sub >= m_char;
sl@0:       ignore_unused_variable_warning(b);
sl@0: 
sl@0:       b = m_char == m_sub;
sl@0:       ignore_unused_variable_warning(b);
sl@0:       b = m_char != m_sub;
sl@0:       ignore_unused_variable_warning(b);
sl@0:       b = m_char <= m_sub;
sl@0:       ignore_unused_variable_warning(b);
sl@0:       b = m_char <= m_sub;
sl@0:       ignore_unused_variable_warning(b);
sl@0:       b = m_char > m_sub;
sl@0:       ignore_unused_variable_warning(b);
sl@0:       b = m_char >= m_sub;
sl@0:       ignore_unused_variable_warning(b);
sl@0: 
sl@0:       b = m_sub == m_string;
sl@0:       ignore_unused_variable_warning(b);
sl@0:       b = m_sub != m_string;
sl@0:       ignore_unused_variable_warning(b);
sl@0:       b = m_sub <= m_string;
sl@0:       ignore_unused_variable_warning(b);
sl@0:       b = m_sub <= m_string;
sl@0:       ignore_unused_variable_warning(b);
sl@0:       b = m_sub > m_string;
sl@0:       ignore_unused_variable_warning(b);
sl@0:       b = m_sub >= m_string;
sl@0:       ignore_unused_variable_warning(b);
sl@0: 
sl@0:       b = m_string == m_sub;
sl@0:       ignore_unused_variable_warning(b);
sl@0:       b = m_string != m_sub;
sl@0:       ignore_unused_variable_warning(b);
sl@0:       b = m_string <= m_sub;
sl@0:       ignore_unused_variable_warning(b);
sl@0:       b = m_string <= m_sub;
sl@0:       ignore_unused_variable_warning(b);
sl@0:       b = m_string > m_sub;
sl@0:       ignore_unused_variable_warning(b);
sl@0:       b = m_string >= m_sub;
sl@0:       ignore_unused_variable_warning(b);
sl@0: 
sl@0:       // match results:
sl@0:       m_string = m_results.str();
sl@0:       ignore_unused_variable_warning(m_string);
sl@0:       m_string = m_results.str(0);
sl@0:       ignore_unused_variable_warning(m_string);
sl@0:       m_out = m_cresults.format(m_out, m_string);
sl@0:       m_out = m_cresults.format(m_out, m_string, m_mft);
sl@0:       m_string = m_cresults.format(m_string);
sl@0:       ignore_unused_variable_warning(m_string);
sl@0:       m_string = m_cresults.format(m_string, m_mft);
sl@0:       ignore_unused_variable_warning(m_string);
sl@0: 
sl@0:       // regex_match:
sl@0:       b = global_regex_namespace::regex_match(m_string, m_smatch, e);
sl@0:       ignore_unused_variable_warning(b);
sl@0:       b = global_regex_namespace::regex_match(m_string, m_smatch, e, m_mft);
sl@0:       ignore_unused_variable_warning(b);
sl@0:       b = global_regex_namespace::regex_match(m_string, e);
sl@0:       ignore_unused_variable_warning(b);
sl@0:       b = global_regex_namespace::regex_match(m_string, e, m_mft);
sl@0:       ignore_unused_variable_warning(b);
sl@0: 
sl@0:       // regex_search:
sl@0:       b = global_regex_namespace::regex_search(m_string, m_smatch, e);
sl@0:       ignore_unused_variable_warning(b);
sl@0:       b = global_regex_namespace::regex_search(m_string, m_smatch, e, m_mft);
sl@0:       ignore_unused_variable_warning(b);
sl@0:       b = global_regex_namespace::regex_search(m_string, e);
sl@0:       ignore_unused_variable_warning(b);
sl@0:       b = global_regex_namespace::regex_search(m_string, e, m_mft);
sl@0:       ignore_unused_variable_warning(b);
sl@0: 
sl@0:       // regex_replace:
sl@0:       m_out = global_regex_namespace::regex_replace(m_out, m_in, m_in, e, m_string, m_mft);
sl@0:       m_out = global_regex_namespace::regex_replace(m_out, m_in, m_in, e, m_string);
sl@0:       m_string = global_regex_namespace::regex_replace(m_string, e, m_string, m_mft);
sl@0:       ignore_unused_variable_warning(m_string);
sl@0:       m_string = global_regex_namespace::regex_replace(m_string, e, m_string);
sl@0:       ignore_unused_variable_warning(m_string);
sl@0: 
sl@0:    }
sl@0: 
sl@0:    flag_type m_flags;
sl@0:    string_type m_string;
sl@0:    const sub_match_type m_sub;
sl@0:    match_results_type m_results;
sl@0:    pointer_type m_pointer;
sl@0:    value_type m_char;
sl@0:    const match_results_type m_cresults;
sl@0:    OutIterator m_out;
sl@0:    BidiIterator m_in;
sl@0:    global_regex_namespace::regex_constants::match_flag_type m_mft;
sl@0:    global_regex_namespace::match_results<typename string_type::const_iterator> m_smatch;
sl@0: 
sl@0:    RegexConcept();
sl@0:    RegexConcept(const RegexConcept&);
sl@0:    RegexConcept& operator=(const RegexConcept&);
sl@0: };
sl@0: 
sl@0: #ifndef BOOST_REGEX_TEST_STD
sl@0: //
sl@0: // BoostRegexConcept:
sl@0: // Test every interface in the Boost implementation:
sl@0: //
sl@0: template <class Regex>
sl@0: struct BoostRegexConcept
sl@0: {
sl@0:    typedef typename Regex::value_type value_type;
sl@0:    typedef typename Regex::size_type size_type;
sl@0:    typedef typename Regex::flag_type flag_type;
sl@0:    typedef typename Regex::locale_type locale_type;
sl@0: 
sl@0:    // derived test types:
sl@0:    typedef const value_type* pointer_type;
sl@0:    typedef std::basic_string<value_type> string_type;
sl@0:    typedef typename Regex::const_iterator const_iterator;
sl@0:    typedef bidirectional_iterator_archetype<value_type> BidiIterator;
sl@0:    typedef global_regex_namespace::sub_match<BidiIterator> sub_match_type;
sl@0:    typedef global_regex_namespace::match_results<BidiIterator> match_results_type;
sl@0: 
sl@0:    void constraints() 
sl@0:    {
sl@0:       global_regex_namespace::regex_constants::match_flag_type mopts
sl@0:          = global_regex_namespace::regex_constants::match_default
sl@0:          | global_regex_namespace::regex_constants::match_not_bol
sl@0:          | global_regex_namespace::regex_constants::match_not_eol
sl@0:          | global_regex_namespace::regex_constants::match_not_bow
sl@0:          | global_regex_namespace::regex_constants::match_not_eow
sl@0:          | global_regex_namespace::regex_constants::match_any
sl@0:          | global_regex_namespace::regex_constants::match_not_null
sl@0:          | global_regex_namespace::regex_constants::match_continuous
sl@0:          | global_regex_namespace::regex_constants::match_partial
sl@0:          | global_regex_namespace::regex_constants::match_prev_avail
sl@0:          | global_regex_namespace::regex_constants::format_default
sl@0:          | global_regex_namespace::regex_constants::format_sed
sl@0:          | global_regex_namespace::regex_constants::format_perl
sl@0:          | global_regex_namespace::regex_constants::format_no_copy
sl@0:          | global_regex_namespace::regex_constants::format_first_only;
sl@0: 
sl@0:       (void)mopts;
sl@0: 
sl@0:       function_requires<RegexConcept<Regex> >();
sl@0:       const global_regex_namespace::regex_error except(global_regex_namespace::regex_constants::error_collate);
sl@0:       std::ptrdiff_t pt = except.position();
sl@0:       ignore_unused_variable_warning(pt);
sl@0:       const Regex ce, ce2;
sl@0: #ifndef BOOST_NO_STD_LOCALE
sl@0:       m_stream << ce;
sl@0: #endif
sl@0:       unsigned i = ce.error_code();
sl@0:       ignore_unused_variable_warning(i);
sl@0:       pointer_type p = ce.expression();
sl@0:       ignore_unused_variable_warning(p);
sl@0:       int i2 = ce.compare(ce2);
sl@0:       ignore_unused_variable_warning(i2);
sl@0:       bool b = ce == ce2;
sl@0:       ignore_unused_variable_warning(b);
sl@0:       b = ce != ce2;
sl@0:       ignore_unused_variable_warning(b);
sl@0:       b = ce < ce2;
sl@0:       ignore_unused_variable_warning(b);
sl@0:       b = ce > ce2;
sl@0:       ignore_unused_variable_warning(b);
sl@0:       b = ce <= ce2;
sl@0:       ignore_unused_variable_warning(b);
sl@0:       b = ce >= ce2;
sl@0:       ignore_unused_variable_warning(b);
sl@0:       i = ce.status();
sl@0:       ignore_unused_variable_warning(i);
sl@0:       size_type s = ce.max_size();
sl@0:       ignore_unused_variable_warning(s);
sl@0:       s = ce.size();
sl@0:       ignore_unused_variable_warning(s);
sl@0:       const_iterator pi = ce.begin();
sl@0:       ignore_unused_variable_warning(pi);
sl@0:       pi = ce.end();
sl@0:       ignore_unused_variable_warning(pi);
sl@0:       string_type s2 = ce.str();
sl@0:       ignore_unused_variable_warning(s2);
sl@0: 
sl@0:       m_string = m_sub + m_sub;
sl@0:       ignore_unused_variable_warning(m_string);
sl@0:       m_string = m_sub + m_pointer;
sl@0:       ignore_unused_variable_warning(m_string);
sl@0:       m_string = m_pointer + m_sub;
sl@0:       ignore_unused_variable_warning(m_string);
sl@0:       m_string = m_sub + m_string;
sl@0:       ignore_unused_variable_warning(m_string);
sl@0:       m_string = m_string + m_sub;
sl@0:       ignore_unused_variable_warning(m_string);
sl@0:       m_string = m_sub + m_char;
sl@0:       ignore_unused_variable_warning(m_string);
sl@0:       m_string = m_char + m_sub;
sl@0:       ignore_unused_variable_warning(m_string);
sl@0: 
sl@0: #ifndef BOOST_NO_STD_LOCALE
sl@0:       m_stream << m_sub;
sl@0:       m_stream << m_cresults;
sl@0: #endif
sl@0:    }
sl@0: 
sl@0:    std::basic_ostream<value_type> m_stream;
sl@0:    sub_match_type m_sub;
sl@0:    pointer_type m_pointer;
sl@0:    string_type m_string;
sl@0:    const value_type m_char;
sl@0:    match_results_type m_results;
sl@0:    const match_results_type m_cresults;
sl@0: 
sl@0:    BoostRegexConcept();
sl@0:    BoostRegexConcept(const BoostRegexConcept&);
sl@0:    BoostRegexConcept& operator=(const BoostRegexConcept&);
sl@0: };
sl@0: 
sl@0: #endif // BOOST_REGEX_TEST_STD
sl@0: 
sl@0: }
sl@0: 
sl@0: #endif