~blep/cppunit2/cpptl-integration

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
// typedispatchpoc.cpp : Defines the entry point for the console application.
// implementation not accepted: cause internal compiler error on MSVC 6.0
// When both CPPUT_SET_DEFAULT_SUITE & CPPUT_SUITE are used.

#include "stdio.h"

#define CPPTL_JOIN( symbol1, symbol2 ) _CPPTL_DO_JOIN( symbol1, symbol2 )

/// \internal
#define _CPPTL_DO_JOIN( symbol1, symbol2 ) _CPPTL_DO_JOIN2( symbol1, symbol2 )

/// \internal
#define _CPPTL_DO_JOIN2( symbol1, symbol2 ) symbol1##symbol2
#define CPPTL_MAKE_UNIQUE_NAME( prefix ) CPPTL_JOIN( prefix, __LINE__ )


namespace CppUT {
   namespace Impl {
      class RegistryImpl;
      class SuiteImpl;

      template<const int size>
      struct RootSuiteSelectorType
      {
      };

      typedef int HasRootSuiteOverrideType;
      typedef char UseDefaultRootSuiteType;
      typedef RootSuiteSelectorType< 
         sizeof(HasRootSuiteOverrideType) > RootSuiteOverridenSelector;
      typedef RootSuiteSelectorType< 
         sizeof(UseDefaultRootSuiteType) > DefaultRootSuiteSelector;

      /// Static object to create a new root suite.
      struct RootSuiteDecl
      {
         explicit RootSuiteDecl( const char *name,
                                 RootSuiteDecl )
		    {
			    printf( "RootSuiteDecl, RootSuiteDecl: %s\n", name );
		    }
         explicit RootSuiteDecl( const char *name,
                                 DefaultRootSuiteSelector )
		    {
			    printf( "RootSuiteDecl, DefaultRootSuiteSelector: %s\n", name );
		    }
      };

      /// Static object to create a new default root suite.
      /// If non default root suite are created, they will be parent to the
      /// default root suite.
      struct DefaultRootSuiteDecl
      {
         explicit DefaultRootSuiteDecl( const char *name,
                                        RootSuiteOverridenSelector )
		    {
			    printf( "DefaultRootSuiteDecl, RootSuiteOverridenSelector: %s\n", name );
		    }
         explicit DefaultRootSuiteDecl( const char *name,
                                        DefaultRootSuiteSelector )
		    {
			    printf( "DefaultRootSuiteDecl, DefaultRootSuiteSelector: %s\n", name );
		    }
      };

      // Another overload for short is declared when a root suite is defined.
      // This allow determining if a root suite has been defined by
      // checking the returning type of: cpputRootSuiteSelector( short ).
      UseDefaultRootSuiteType cpputRootSuiteSelector( int dummy );

      namespace Hidden {
         HasRootSuiteOverrideType cpputRootSuiteSelector( short dummy );
      } // namespace Hidden

      // This macro expand into a type used to select which overload of
      // currentSuite() is selected.
      // It relies on the fact that in case of overloading, the most specialized
      // overload is selected.
      // The cpputRootSuiteSelector() is defined by default to accept an int
      // as parameter. When a root suite is set, an overload is injected that 
      // accept a short as a paramter.
      // Therefore the call:
      // cpputRootSuiteSelector(short(1)): is resolved to function
      // UseDefaultRootSuiteType cpputRootSuiteSelector(int) if no 
      // root has been defined, and
      // HasRootSuiteOverrideType cpputRootSuiteSelector(short) if a
      // root has been defined.
      #define _CPPUT_SELECT_ROOTSUITETYPE()                                   \
         ::CppUT::Impl::RootSuiteSelectorType<                                \
            sizeof(cpputRootSuiteSelector(short(1))) >()

      // currentSuite() rely on type dispatch to determine
      // if the default suite has been overridden in the current translation unit.
      const char *currentSuite( RootSuiteOverridenSelector )
      {
         return "currentSuite( RootSuiteOverridenSelector )";
      }

      const char *currentSuite( DefaultRootSuiteSelector )
      {
         return "currentSuite( DefaultRootSuiteSelector )";
      }
   } // namespace Impl

// internal
#define _CPPUT_DECLARE_ROOT_SUITE( name, DeclType )               \
   static ::CppUT::Impl::DeclType                                 \
      CPPTL_MAKE_UNIQUE_NAME(cpputRootSuite)(                     \
            name,                                                 \
            _CPPUT_SELECT_ROOTSUITETYPE() );                      \
   using ::CppUT::Impl::Hidden::cpputRootSuiteSelector
} // namespace CppUT




#define CPPUT_SET_DEFAULT_SUITE( name )                           \
   namespace {                                                    \
      _CPPUT_DECLARE_ROOT_SUITE( name, DefaultRootSuiteDecl );    \
   }

#define CPPUT_SUITE( name )                              \
   _CPPUT_DECLARE_ROOT_SUITE( name, RootSuiteDecl );     \
   namespace



using ::CppUT::Impl::cpputRootSuiteSelector;

/// end framework


CPPUT_SET_DEFAULT_SUITE( "my default" );

CPPUT_SUITE( "sub root suite" ) {
}

/*
_CPPUT_DECLARE_ROOT_SUITE( "toto" );
namespace {
}

_CPPUT_DECLARE_ROOT_SUITE( "tata" );

_CPPUT_DECLARE_ROOT_SUITE( "titi" );

*/

namespace {
const char *value = CppUT::Impl::currentSuite( _CPPUT_SELECT_ROOTSUITETYPE() );
}

int main(int argc, char* argv[])
{
   //printf( "Size: %d\n", 
   //   sizeof cpputRootSuiteSelector(short(1)) );
   printf( "Selected: %s\n", value );
   return 0;
}