check.h

00001 /*
00002  * ASTL - the Automaton Standard Template Library.
00003  * C++ generic components for Finite State Automata handling.
00004  * Copyright (C) 2000-2003 Vincent Le Maout (vincent.lemaout@chello.fr).
00005  * 
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Lesser General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2.1 of the License, or (at your option) any later version.
00010  * 
00011  * This library is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  * 
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with this library; if not, write to the Free Software
00018  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019  *
00020  */
00021 
00022 #ifndef ASTL_CHECK_H
00023 #define ASTL_CHECK_H
00024 
00025 #include <concept.h>
00026 #include <iostream>
00027 #include <string>
00028 
00029 using std::cout;
00030 using std::endl;
00031 using std::string;
00032 
00033 namespace astl {
00034 
00035 // Check if the interface conforms to the concept:
00036 
00037 template <typename T>
00038 void check(const T &c, const string& class_name, 
00039 #ifdef _MSC_VER
00040            const typename T::char_type &a = T::char_type())
00041 #else
00042            const typename T::char_type &a = typename T::char_type())
00043 #endif
00044 {
00045   cout << "Checking " << class_name << "..." << endl;
00046   check_(c, c, class_name, a);
00047 }
00048 
00049 template <typename T>
00050 void check_trivial_cursor_requirements(const T &c1, const string& class_name, 
00051                                        const typename T::char_type & = typename T::char_type())
00052 {
00053   typedef typename T::state_type state_type;
00054   typedef typename T::tag_type   tag_type;
00055   typedef typename T::char_type  char_type;
00056   cout << "* trivial cursor requirements" << endl;
00057   cout << "\t" << class_name << "::" << class_name << "()" << endl;
00058   T c2;
00059   cout << "\t" << class_name << "::" << class_name << "(" << class_name << ")" << endl;
00060   T c3 = c2;
00061   cout << "\t" << class_name << "::operator=(" << class_name << ")" << endl;
00062   c3 = c2 = c1;                      // assignable, copy constructible
00063   cout << "\t" << class_name << "::operator==(" << class_name << ")" << endl;
00064   bool b = c1 == c2;                   // equality comparable
00065   cout << "\t" << class_name << "::sink()" << endl;
00066   b = c1.sink();                       // bool sink() const;
00067   cout << "\t" << class_name << "::sink_state()" << endl;
00068   c1.sink_state();      // state_type sink_state() const;
00069   cout << "\t" << class_name << "::state_type::state_type()" << endl;
00070   state_type s;
00071   cout << "\t" << class_name << "::state_type::state_type(state_type)" << endl;
00072   state_type ss = c1.sink_state();
00073   cout << "\t" << class_name << "::state_type::operator=(state_type)" << endl;
00074   s = ss;
00075   cout << "\t" << class_name << "::state_type::operator==(state_type)" << endl;
00076   b = ss == s;
00077   cout << "\t" << class_name << "::state_type::operator<(state_type)" << endl;
00078   b = ss < s;                
00079   cout << "\t" << class_name << "::src()" << endl;
00080   state_type q = c1.src();  
00081   q = q;
00082   cout << "\t" << class_name << "::src_final()" << endl;
00083   b = c1.src_final();                  // bool src_final() const;
00084   cout << "\t" << class_name << "::operator=(state_type)" << endl;
00085   c2 = c1.sink_state();                // T::operator=(state_type);
00086   cout << "\t" << class_name << "::tag_type::tag_type()" << endl;
00087   tag_type t2;
00088   cout << "\t" << class_name << "::tag_type::tag_type(tag_type)" << endl;
00089   tag_type t1 = t2;
00090   cout << "\t" << class_name << "::tag_type::operator=(tag_type)" << endl;
00091   t1 = t2;
00092   cout << "\t" << class_name << "::src_tag()" << endl;
00093   t1 = c1.src_tag();          // tag_type src_tag() const, tag_type::tag_type(tag_type)
00094 }
00095 
00096 // The cursor must be in a valid state:
00097 template <typename T>
00098 void check_(const T &c, cursor_concept, const string& class_name, 
00099             const typename T::char_type &a = typename T::char_type())
00100 {
00101   T cc = c;
00102   check_trivial_cursor_requirements(c, class_name, a);
00103   cout << "* plain cursor requirements" << endl;
00104   cout << "\t" << class_name << "::exists(char_type)" << endl;
00105   bool b = cc.exists(a);
00106   cout << "\t" << class_name << "::forward(char_type)" << endl;
00107   b = cc.forward(a);
00108 }
00109 
00110 template <typename T>
00111 void check_(const T &c, transition_cursor_concept, const string& class_name, 
00112             const typename T::char_type &a = typename T::char_type())
00113 {
00114   bool b;
00115   T cc = c;
00116   check_trivial_cursor_requirements(c, class_name, a);
00117   cout << "* transition cursor requirements" << endl;
00118   typedef typename T::char_traits char_traits;
00119   cout << "\t" << class_name << "::first()" << endl;
00120   b = cc.first();
00121   cout << "\t" << class_name << "::letter()" << endl;
00122   typename T::char_type aa = cc.letter();
00123   aa = aa; // just to avoid annoying warnings about unused variables
00124   T d = cc;
00125   cout << "\t" << class_name << "::forward()" << endl;
00126   d.forward();
00127   cout << "\t" << class_name << "::next()" << endl;
00128   b = cc.next();
00129   cc.first();
00130   cout << "\t" << class_name << "::aim()" << endl;
00131   typename T::state_type q = cc.aim();
00132   q = q;
00133   cout << "\t" << class_name << "::aim_final()" << endl;
00134   b = cc.aim_final();
00135   cout << "\t" << class_name << "::aim_tag()" << endl;
00136   typename T::tag_type t = cc.aim_tag();
00137 }
00138 
00139 template <typename T>
00140 void check_(const T &c, forward_cursor_concept, const string& class_name, 
00141             const typename T::char_type &a = typename T::char_type())
00142 {
00143   T cc = c;
00144   check_(cc, cursor_concept(), class_name, a);
00145   check_(cc, transition_cursor_concept(), class_name, a);
00146   cout << "* forward cursor requirements" << endl;
00147   cout << "\t" << class_name << "::find(char_type)" << endl;
00148   bool b = cc.find(a);
00149   b = b;
00150 }
00151 
00152 } // namespace astl
00153 
00154 #endif // ASTL_CHECK_H

Generated on Sun Mar 8 02:41:30 2009 for ASTL by  doxygen 1.5.7.1