source: src/Patterns/Factory_impl.hpp@ 746ff1

Last change on this file since 746ff1 was 746ff1, checked in by Frederik Heber <heber@…>, 15 years ago

Added Creator and Factory pattern.

  • unittests added.
  • new subfolder stubs that contains stubs for Creator and Factory.
  • the only preprocessor stuff is in Factory_impl.hpp.
  • FactoryTypeList.hpp is necessary as long as no variadic template argument lists are possible.
  • library version is 2:0:0, API version is 1.0.2.
  • Property mode set to 100644
File size: 4.0 KB
Line 
1/*
2 * Factory_impl_specific.hpp
3 *
4 * Created on: Jan 3, 2011
5 * Author: heber
6 */
7
8// include config.h
9#ifdef HAVE_CONFIG_H
10#include <config.h>
11#endif
12
13#include <boost/preprocessor/debug/assert.hpp>
14#include <boost/preprocessor/facilities/empty.hpp>
15#include <boost/preprocessor/iteration/local.hpp>
16#include <boost/preprocessor/punctuation/comma.hpp>
17#include <boost/preprocessor/punctuation/comma_if.hpp>
18#include <boost/preprocessor/seq/elem.hpp>
19#include <boost/preprocessor/seq/size.hpp>
20#include <boost/preprocessor/stringize.hpp>
21
22// check for required type_seq
23#ifdef type_seq
24#define type_seq_size BOOST_PP_SEQ_SIZE(type_seq)
25#else
26BOOST_PP_ASSERT_MSG( 0 , \
27 "std::cout << \"missing type_seq for creating Factory<T>\" << std::endl")
28#define type_seq ()
29#endif
30
31// check for required Abstract_Interface_Class
32#ifndef Abstract_Interface_Class
33 BOOST_PP_ASSERT_MSG( 0 , \
34 "std::cout << \"missing Abstract_Interface_Class for creating Factory<T>\" << std::endl")
35#define Abstract_Interface_Class NONE
36#endif
37
38// check for required Abstract_Encapsulation_Class
39#ifndef Abstract_Encapsulation_Class
40 BOOST_PP_ASSERT_MSG( 0 , \
41 "std::cout << \"missing Abstract_Encapsulation_Class for creating Factory<T>\" << std::endl")
42#define Abstract_Encapsulation_Class NONE
43#endif
44
45// check for type_name_space, is only optional
46#ifndef type_name_space
47#define type_name_space BOOST_PP_EMPTY()
48#endif
49
50#ifndef type_name_space_suffix
51#define type_name_space_suffix BOOST_PP_EMPTY()
52#endif
53
54/** Functions that allows to print a given seq of elements in the way of
55 * std::map from strings to enums.
56 *
57 * e.g. let "seq" be defined as
58 * #define seq (one)(two)(three)(four)
59 *
60 * then we use
61 * #define BOOST_PP_LOCAL_MACRO(n) seqitems_as_string_enum_map(seqsize, n, seq, EnumMap, name_space)
62 * #define BOOST_PP_LOCAL_LIMITS (0, BOOST_PP_SEQ_SIZE(seq)-1 )
63 * #include BOOST_PP_LOCAL_ITERATE()
64 *
65 * which expands by the preprocessor to:
66 * EnumMap["one"] = test:: one;
67 * EnumMap["two"] = test:: two;
68 * EnumMap["three"] = test:: three;
69 * EnumMap["four"] = test:: four;
70
71 */
72#define seqitems_as_string_enum_map(z,n,seq_with_elements, map, name_space) \
73 map [BOOST_PP_STRINGIZE( \
74 BOOST_PP_SEQ_ELEM(n, seq_with_elements) \
75 )] = name_space BOOST_PP_SEQ_ELEM(n, seq_with_elements) \
76 ;
77
78/** Functions that allows to print a given seq of elements in the way of
79 * std::map from strings to enums.
80 *
81 * e.g. let "seq" be defined as
82 * #define seq (one)(two)(three)(four)
83 *
84 * then we use
85 * #define BOOST_PP_LOCAL_MACRO(n) seqitems_as_enum_key_map(seqsize, n, seq, EnumMap, test::)
86 * #define BOOST_PP_LOCAL_LIMITS (0, BOOST_PP_SEQ_SIZE(seq)-1 )
87 * #include BOOST_PP_LOCAL_ITERATE()
88 *
89 * which expands by the preprocessor to:
90 * EnumMap[one] = test::one;
91 * EnumMap[two] = test::two;
92 * EnumMap[three] = test::three;
93 * EnumMap[four] = test::four;
94
95 */
96#define seqitems_as_enum_key_map(z,n,seq_with_elements, map, keytype, name_space, suffix) \
97 map [ \
98 BOOST_PP_SEQ_ELEM(n, seq_with_elements) \
99 ] = keytype< name_space BOOST_PP_SEQ_ELEM(n, seq_with_elements) suffix > ();
100
101
102template <>
103void Factory<Abstract_Interface_Class>::FillEnumTable()
104{
105 // insert all known (enum, string) keys
106#define BOOST_PP_LOCAL_MACRO(n) seqitems_as_string_enum_map(~, n, type_seq, enums, FactoryTypeList<Abstract_Interface_Class>::)
107#define BOOST_PP_LOCAL_LIMITS (0, BOOST_PP_SEQ_SIZE(type_seq)-1 )
108#include BOOST_PP_LOCAL_ITERATE()
109
110 // create invert mapping (string, enum)
111 for (Factory<Abstract_Interface_Class>::EnumMap::const_iterator iter = enums.begin();
112 iter != enums.end();
113 ++iter) {
114 names.insert(make_pair(iter->second, iter->first));
115 }
116}
117
118template <>
119void Factory<Abstract_Interface_Class>::FillPrototypeTable()
120{
121 // fill PrototypeTable
122#define BOOST_PP_LOCAL_MACRO(n) seqitems_as_enum_key_map(~, n, type_seq, PrototypeTable, new Creator< Abstract_Interface_Class BOOST_PP_COMMA() Abstract_Encapsulation_Class, type_name_space, type_name_space_suffix > )
123#define BOOST_PP_LOCAL_LIMITS (0, BOOST_PP_SEQ_SIZE(type_seq)-1 )
124#include BOOST_PP_LOCAL_ITERATE()
125}
126
Note: See TracBrowser for help on using the repository browser.