6
6
namespace autowiring {
7
7
struct config_registry_entry_base {
8
8
protected:
9
- config_registry_entry_base (void );
9
+ config_registry_entry_base (config_descriptor&& descriptor );
10
10
11
11
public:
12
12
// Next entry in the registry:
13
- config_registry_entry_base* pFlink = nullptr ;
13
+ const config_registry_entry_base* const pFlink = nullptr ;
14
+
15
+ // Descriptor proper:
16
+ const config_descriptor descriptor;
14
17
};
15
18
16
19
struct config_registry_entry_default {
17
- static const config_descriptor desc;
20
+ config_registry_entry_default (void );
21
+
22
+ config_descriptor descriptor;
23
+
24
+ static const config_registry_entry_default entry;
18
25
};
19
26
20
27
template <typename T, typename = void >
@@ -26,21 +33,81 @@ namespace autowiring {
26
33
struct config_registry_entry <T, typename std::enable_if<has_getconfigdescriptor<T>::value>::type> :
27
34
config_registry_entry_base
28
35
{
36
+ private:
37
+ config_registry_entry (void ) :
38
+ config_registry_entry_base (T::GetConfigDescriptor())
39
+ {}
40
+
29
41
public:
30
- static const config_descriptor desc ;
42
+ static const config_registry_entry entry ;
31
43
};
32
44
33
45
template <typename T>
34
- const config_descriptor config_registry_entry<T, typename std::enable_if<has_getconfigdescriptor<T>::value>::type>::desc = T::GetConfigDescriptor();
46
+ const config_registry_entry<T, typename std::enable_if<has_getconfigdescriptor<T>::value>::type>
47
+ config_registry_entry<T, typename std::enable_if<has_getconfigdescriptor<T>::value>::type>::entry;
48
+
49
+ struct config_registry {
50
+ // / <summary>
51
+ // / Standard iterator type
52
+ // / </summary>
53
+ class const_iterator {
54
+ public:
55
+ typedef std::forward_iterator_tag iterator_category;
56
+ typedef std::ptrdiff_t difference_type;
57
+ typedef config_registry_entry_base value_type;
58
+ typedef const config_descriptor* pointer;
59
+ typedef const config_descriptor& reference;
60
+
61
+ const_iterator (const config_registry_entry_base* entry = nullptr ) :
62
+ m_cur (entry)
63
+ {}
64
+
65
+ private:
66
+ const config_registry_entry_base* m_cur;
35
67
36
- extern std::atomic<config_registry_entry_base*> g_pFirstEntry;
68
+ public:
69
+ pointer operator ->(void ) const { return &m_cur->descriptor ; }
70
+ reference operator *(void ) { return m_cur->descriptor ; }
71
+
72
+ bool operator ==(const const_iterator& rhs) const { return m_cur == rhs.m_cur ; }
73
+ bool operator !=(const const_iterator& rhs) const { return m_cur != rhs.m_cur ; }
74
+
75
+ // Iterator operator overloads:
76
+ const_iterator& operator ++(void ) {
77
+ m_cur = m_cur->pFlink ;
78
+ return *this ;
79
+ }
80
+ const_iterator operator ++(int ) {
81
+ auto prior = m_cur;
82
+ ++*this ;
83
+ return { prior };
84
+ }
85
+ };
86
+
87
+ private:
88
+ // Application linked list head
89
+ static config_registry_entry_base* g_pFirstEntry;
90
+
91
+ public:
92
+ // / <summary>
93
+ // / Adds a link to the specified registry entry
94
+ // / </summary>
95
+ // / <remarks>
96
+ // / This routine is not thread safe, and must be externally synchronized
97
+ // / </remarks>
98
+ static const config_registry_entry_base* Link (config_registry_entry_base& entry);
99
+
100
+ // Iterator support logic:
101
+ const_iterator begin (void ) const { return { g_pFirstEntry }; }
102
+ const_iterator end (void ) const { return { nullptr }; }
103
+ };
37
104
38
105
// / <summary>
39
106
// / Gets a string representation of the named configuration value
40
107
// / </summary>
41
108
template <typename T>
42
109
std::string ConfigGet (const char * name, T& obj) {
43
- const config_descriptor& desc = config_registry_entry<T>::desc ;
110
+ const config_descriptor& desc = config_registry_entry<T>::entry. descriptor ;
44
111
auto q = desc.fields .find (name);
45
112
if (q == desc.fields .end ())
46
113
throw std::invalid_argument (" Configuration name not found in the specified object's configuration descriptor" );
@@ -54,7 +121,7 @@ namespace autowiring {
54
121
// / </summary>
55
122
template <typename T>
56
123
void ConfigSet (const char * name, T& obj, const char * value) {
57
- const config_descriptor& desc = config_registry_entry<T>::desc ;
124
+ const config_descriptor& desc = config_registry_entry<T>::entry. descriptor ;
58
125
auto q = desc.fields .find (name);
59
126
if (q == desc.fields .end ())
60
127
throw std::invalid_argument (" Configuration name not found in the specified object's configuration descriptor" );
0 commit comments