Vaucanson  1.4.1
constraints.hh
1 // constraints.hh: this file is part of the Vaucanson project.
2 //
3 // Vaucanson, a generic library for finite state machines.
4 //
5 // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 The Vaucanson Group.
6 //
7 // This program is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU General Public License
9 // as published by the Free Software Foundation; either version 2
10 // of the License, or (at your option) any later version.
11 //
12 // The complete GNU General Public Licence Notice can be found as the
13 // `COPYING' file in the root directory.
14 //
15 // The Vaucanson Group consists of people listed in the `AUTHORS' file.
16 //
17 #ifndef VCSN_MISC_CONSTRAINTS_HH
18 # define VCSN_MISC_CONSTRAINTS_HH
19 
20 
21 namespace vcsn
22 {
23  namespace misc
24  {
25 
26  /*---------------------------.
27  | Static constraint checking |
28  `---------------------------*/
29 
30  // this stuff is heavily inspired from the C++ Boost Library.
31  // Use it sparingly, it can cause HUGE amounts of template instanciations.
32 
33 # if defined(__GNUC__)
34 # define UnusedConceptVar __attribute__ ((__unused__))
35 # else
36 # define UnusedConceptVar /* unused */
37 # endif
38 
39  namespace concepts
40  {
41  template <typename Concept_>
42  static void function_requires()
43  {
44  void (Concept_::*ptr)() UnusedConceptVar = &Concept_::constraints;
45  }
46 
47  // deep wizardry at work here...
48 
49 # define MISC_CLASS_CHECKING_IDX(Lineno, Concept, T) \
50  ConceptChecking ## Lineno ## _ ## Concept ## T
51 # define MISC_CLASS_CHECKING_ID(Lineno, Concept, T) \
52  MISC_CLASS_CHECKING_IDX(Lineno, Concept, T)
53 # define MISC_CLASS_FPTR_IDX(Lineno, Concept, T) \
54  Concept ## Lineno ## _fptr_ ## T
55 # define MISC_CLASS_FPTR_ID(Lineno, Concept, T) \
56  MISC_CLASS_FPTR_IDX(Lineno, Concept, T)
57 
58 # ifdef VCSN_NDEBUG
59 
60 # define MISC_CLASS_REQUIRE_CONCEPT(Var, Namespace, Concept) \
61  typedef void MISC_CLASS_CHECKING_ID(__LINE__, Concept, _t)
62 # define MISC_CLASS_REQUIRE_CONCEPT2(Var1, Var2, Namespace, Concept) \
63  typedef void MISC_CLASS_CHECKING_ID(__LINE__, Concept, _t)
64 # define MISC_CLASS_REQUIRE_CONCEPT3(Var1, Var2, Var3, Namespace, Concept) \
65  typedef void MISC_CLASS_CHECKING_ID(__LINE__, Concept, _t)
66 # define MISC_CLASS_REQUIRE_CONCEPT4(Var1, Var2, Var3, Var4, Namespace, Concept) \
67  typedef void MISC_CLASS_CHECKING_ID(__LINE__, Concept, _t)
68 # define MISC_REQUIRE_CONCEPT(Var, Namespace, Concept) \
69  typedef void MISC_CLASS_CHECKING_ID(__LINE__, Concept, _t)
70 # define MISC_REQUIRE_CONCEPT2(Var1, Var2, Namespace, Concept) \
71  typedef void MISC_CLASS_CHECKING_ID(__LINE__, Concept, _t)
72 # define MISC_REQUIRE_CONCEPT3(Var1, Var2, Var3, Namespace, Concept) \
73  typedef void MISC_CLASS_CHECKING_ID(__LINE__, Concept, _t)
74 # define MISC_REQUIRE_CONCEPT4(Var1, Var2, Var3, Var4, Namespace, Concept) \
75  typedef void MISC_CLASS_CHECKING_ID(__LINE__, Concept, _t)
76 
77 # else // VCSN_NDEBUG
78 
79  // these should be left 120 columns wide for better readability
80 
81 # define MISC_CLASS_REQUIRE_CONCEPT(Var, Namespace, Concept) \
82  typedef void (Namespace::Concept <Var>::* MISC_CLASS_FPTR_ID(__LINE__, Concept, t))(); \
83  template <MISC_CLASS_FPTR_ID(__LINE__, Concept, t) MISC_CLASS_FPTR_ID(__LINE__, Concept, arg)> \
84  struct MISC_CLASS_CHECKING_ID(__LINE__, Concept, _s) {}; \
85  typedef MISC_CLASS_CHECKING_ID(__LINE__, Concept, _s)<& Namespace::Concept<Var>::constraints> \
86  MISC_CLASS_CHECKING_ID(__LINE__, Concept, _t)
87 
88 # define MISC_CLASS_REQUIRE_CONCEPT2(Var1, Var2, Namespace, Concept) \
89  typedef void (Namespace::Concept <Var1,Var2>::* MISC_CLASS_FPTR_ID(__LINE__, Concept, t))(); \
90  template <MISC_CLASS_FPTR_ID(__LINE__, Concept, t) MISC_CLASS_FPTR_ID(__LINE__, Concept, arg)> \
91  struct MISC_CLASS_CHECKING_ID(__LINE__, Concept, _s) {}; \
92  typedef MISC_CLASS_CHECKING_ID(__LINE__, Concept, _s)<& Namespace::Concept<Var1,Var2>::constraints> \
93  MISC_CLASS_CHECKING_ID(__LINE__, Concept, _t)
94 
95 # define MISC_CLASS_REQUIRE_CONCEPT3(Var1, Var2, Var3, Namespace, Concept) \
96  typedef void (Namespace::Concept <Var1,Var2,Var3>::* MISC_CLASS_FPTR_ID(__LINE__, Concept, t))(); \
97  template <MISC_CLASS_FPTR_ID(__LINE__, Concept, t) MISC_CLASS_FPTR_ID(__LINE__, Concept, arg)> \
98  struct MISC_CLASS_CHECKING_ID(__LINE__, Concept, _s) {}; \
99  typedef MISC_CLASS_CHECKING_ID(__LINE__, Concept, _s)<& Namespace::Concept<Var1,Var2,Var3>::constraints> \
100  MISC_CLASS_CHECKING_ID(__LINE__, Concept, _t)
101 
102 # define MISC_CLASS_REQUIRE_CONCEPT4(Var1, Var2, Var3, Var4, Namespace, Concept) \
103  typedef void (Namespace::Concept <Var1,Var2,Var3,Var4>::* MISC_CLASS_FPTR_ID(__LINE__, Concept, t))(); \
104  template <MISC_CLASS_FPTR_ID(__LINE__, Concept, t) MISC_CLASS_FPTR_ID(__LINE__, Concept, arg)> \
105  struct MISC_CLASS_CHECKING_ID(__LINE__, Concept, _s) {}; \
106  typedef MISC_CLASS_CHECKING_ID(__LINE__, Concept, _s)<& Namespace::Concept<Var1,Var2,Var3,Var4>::constraints> \
107  MISC_CLASS_CHECKING_ID(__LINE__, Concept, _t)
108 
109 # define MISC_REQUIRE_CONCEPT(Var, Namespace, Concept) \
110  vcsn::misc::concepts::function_requires<Namespace::Concept <Var> >()
111 # define MISC_REQUIRE_CONCEPT2(Var1, Var2, Namespace, Concept) \
112  vcsn::misc::concepts::function_requires<Namespace::Concept <Var1, Var2> >()
113 # define MISC_REQUIRE_CONCEPT3(Var1, Var2, Var3, Namespace, Concept) \
114  vcsn::misc::concepts::function_requires<Namespace::Concept <Var1, Var2, Var3> >()
115 # define MISC_REQUIRE_CONCEPT4(Var1, Var2, Var3, Var4, Namespace, Concept) \
116  vcsn::misc::concepts::function_requires<Namespace::Concept <Var1, Var2, Var3, Var4> >()
117 
118 # endif // ! VCSN_NDEBUG
119 
120  } // concepts
121  } // misc
122 } // vcsn
123 
124 #endif // ! VCSN_MISC_CONSTRAINTS_HH