constraints.hh

00001 // constraints.hh: this file is part of the Vaucanson project.
00002 //
00003 // Vaucanson, a generic library for finite state machines.
00004 //
00005 // Copyright (C) 2001, 2002, 2003, 2004, 2005 The Vaucanson Group.
00006 //
00007 // This program is free software; you can redistribute it and/or
00008 // modify it under the terms of the GNU General Public License
00009 // as published by the Free Software Foundation; either version 2
00010 // of the License, or (at your option) any later version.
00011 //
00012 // The complete GNU General Public Licence Notice can be found as the
00013 // `COPYING' file in the root directory.
00014 //
00015 // The Vaucanson Group consists of people listed in the `AUTHORS' file.
00016 //
00017 #ifndef VCSN_MISC_CONSTRAINTS_HH
00018 # define VCSN_MISC_CONSTRAINTS_HH
00019 
00020 
00021 namespace utility
00022 {
00023 
00024   /*---------------------------.
00025   | Static constraint checking |
00026   `---------------------------*/
00027 
00028   // this stuff is heavily inspired from the C++ Boost Library.
00029   // Use it sparingly, it can cause HUGE amounts of template instanciations.
00030 
00031 # if defined(__GNUC__)
00032 #  define UnusedConceptVar __attribute__ ((__unused__))
00033 # else
00034 #  define UnusedConceptVar /* unused */
00035 # endif
00036 
00037   namespace concepts
00038   {
00039     template <typename Concept_>
00040     static void function_requires()
00041     {
00042       void (Concept_::*ptr)() UnusedConceptVar = &Concept_::constraints;
00043     }
00044 
00045     // deep wizardry at work here...
00046 
00047 # define UTILITY_CLASS_CHECKING_IDX(Lineno, Concept, T) \
00048   ConceptChecking##Lineno##_##Concept##T
00049 # define UTILITY_CLASS_CHECKING_ID(Lineno, Concept, T) \
00050   UTILITY_CLASS_CHECKING_IDX(Lineno, Concept, T)
00051 # define UTILITY_CLASS_FPTR_IDX(Lineno, Concept, T) \
00052   Concept##Lineno##_fptr_##T
00053 # define UTILITY_CLASS_FPTR_ID(Lineno, Concept, T) \
00054   UTILITY_CLASS_FPTR_IDX(Lineno, Concept, T)
00055 
00056 # ifdef VCSN_NDEBUG
00057 
00058 #  define UTILITY_CLASS_REQUIRE_CONCEPT(Var, Namespace, Concept) \
00059     typedef void UTILITY_CLASS_CHECKING_ID(__LINE__, Concept, _t)
00060 #  define UTILITY_CLASS_REQUIRE_CONCEPT2(Var1, Var2, Namespace, Concept) \
00061     typedef void UTILITY_CLASS_CHECKING_ID(__LINE__, Concept, _t)
00062 #  define UTILITY_CLASS_REQUIRE_CONCEPT3(Var1, Var2, Var3, Namespace, Concept) \
00063     typedef void UTILITY_CLASS_CHECKING_ID(__LINE__, Concept, _t)
00064 #  define UTILITY_CLASS_REQUIRE_CONCEPT4(Var1, Var2, Var3, Var4, Namespace, Concept) \
00065     typedef void UTILITY_CLASS_CHECKING_ID(__LINE__, Concept, _t)
00066 #  define UTILITY_REQUIRE_CONCEPT(Var, Namespace, Concept) \
00067     typedef void UTILITY_CLASS_CHECKING_ID(__LINE__, Concept, _t)
00068 #  define UTILITY_REQUIRE_CONCEPT2(Var1, Var2, Namespace, Concept) \
00069     typedef void UTILITY_CLASS_CHECKING_ID(__LINE__, Concept, _t)
00070 #  define UTILITY_REQUIRE_CONCEPT3(Var1, Var2, Var3, Namespace, Concept) \
00071     typedef void UTILITY_CLASS_CHECKING_ID(__LINE__, Concept, _t)
00072 #  define UTILITY_REQUIRE_CONCEPT4(Var1, Var2, Var3, Var4, Namespace, Concept) \
00073     typedef void UTILITY_CLASS_CHECKING_ID(__LINE__, Concept, _t)
00074 
00075 # else // VCSN_NDEBUG
00076 
00077     // these should be left 120 columns wide for better readability
00078 
00079 #  define UTILITY_CLASS_REQUIRE_CONCEPT(Var, Namespace, Concept)                                        \
00080   typedef void (Namespace::Concept <Var>::* UTILITY_CLASS_FPTR_ID(__LINE__, Concept, t))();             \
00081   template <UTILITY_CLASS_FPTR_ID(__LINE__, Concept, t) UTILITY_CLASS_FPTR_ID(__LINE__, Concept, arg)>  \
00082   struct UTILITY_CLASS_CHECKING_ID(__LINE__, Concept, _s) {};                                           \
00083   typedef UTILITY_CLASS_CHECKING_ID(__LINE__, Concept, _s)<& Namespace::Concept<Var>::constraints>      \
00084         UTILITY_CLASS_CHECKING_ID(__LINE__, Concept, _t)
00085 
00086 #  define UTILITY_CLASS_REQUIRE_CONCEPT2(Var1, Var2, Namespace, Concept)                                \
00087   typedef void (Namespace::Concept <Var1,Var2>::* UTILITY_CLASS_FPTR_ID(__LINE__, Concept, t))();       \
00088   template <UTILITY_CLASS_FPTR_ID(__LINE__, Concept, t) UTILITY_CLASS_FPTR_ID(__LINE__, Concept, arg)>  \
00089   struct UTILITY_CLASS_CHECKING_ID(__LINE__, Concept, _s) {};                                           \
00090   typedef UTILITY_CLASS_CHECKING_ID(__LINE__, Concept, _s)<& Namespace::Concept<Var1,Var2>::constraints> \
00091         UTILITY_CLASS_CHECKING_ID(__LINE__, Concept, _t)
00092 
00093 #  define UTILITY_CLASS_REQUIRE_CONCEPT3(Var1, Var2, Var3, Namespace, Concept)                          \
00094   typedef void (Namespace::Concept <Var1,Var2,Var3>::* UTILITY_CLASS_FPTR_ID(__LINE__, Concept, t))();  \
00095   template <UTILITY_CLASS_FPTR_ID(__LINE__, Concept, t) UTILITY_CLASS_FPTR_ID(__LINE__, Concept, arg)>  \
00096   struct UTILITY_CLASS_CHECKING_ID(__LINE__, Concept, _s) {};                                           \
00097   typedef UTILITY_CLASS_CHECKING_ID(__LINE__, Concept, _s)<& Namespace::Concept<Var1,Var2,Var3>::constraints> \
00098         UTILITY_CLASS_CHECKING_ID(__LINE__, Concept, _t)
00099 
00100 #  define UTILITY_CLASS_REQUIRE_CONCEPT4(Var1, Var2, Var3, Var4, Namespace, Concept)                    \
00101   typedef void (Namespace::Concept <Var1,Var2,Var3,Var4>::* UTILITY_CLASS_FPTR_ID(__LINE__, Concept, t))();\
00102   template <UTILITY_CLASS_FPTR_ID(__LINE__, Concept, t) UTILITY_CLASS_FPTR_ID(__LINE__, Concept, arg)>  \
00103   struct UTILITY_CLASS_CHECKING_ID(__LINE__, Concept, _s) {};                                           \
00104   typedef UTILITY_CLASS_CHECKING_ID(__LINE__, Concept, _s)<& Namespace::Concept<Var1,Var2,Var3,Var4>::constraints> \
00105         UTILITY_CLASS_CHECKING_ID(__LINE__, Concept, _t)
00106 
00107 #  define UTILITY_REQUIRE_CONCEPT(Var, Namespace, Concept) \
00108   utility::concepts::function_requires<Namespace::Concept <Var> >()
00109 #  define UTILITY_REQUIRE_CONCEPT2(Var1, Var2, Namespace, Concept) \
00110   utility::concepts::function_requires<Namespace::Concept <Var1, Var2> >()
00111 #  define UTILITY_REQUIRE_CONCEPT3(Var1, Var2, Var3, Namespace, Concept) \
00112   utility::concepts::function_requires<Namespace::Concept <Var1, Var2, Var3> >()
00113 #  define UTILITY_REQUIRE_CONCEPT4(Var1, Var2, Var3, Var4, Namespace, Concept) \
00114   utility::concepts::function_requires<Namespace::Concept <Var1, Var2, Var3, Var4> >()
00115 
00116 # endif // ! VCSN_NDEBUG
00117 
00118   } // concepts
00119 } // utility
00120 
00121 #endif // ! VCSN_MISC_CONSTRAINTS_HH

Generated on Fri Jul 28 12:18:30 2006 for Vaucanson by  doxygen 1.4.6