Ice 3.8
C++ API Reference
Loading...
Searching...
No Matches
DefaultSliceLoader.h
1// Copyright (c) ZeroC, Inc.
2
3#ifndef ICE_DEFAULT_SLICE_LOADER_H
4#define ICE_DEFAULT_SLICE_LOADER_H
5
6#include "SliceLoader.h"
7#include "UserException.h"
8#include <functional>
9#include <map>
10#include <mutex>
11#include <string>
12#include <type_traits>
13
14namespace IceInternal
15{
16 class DefaultSliceLoader;
17 using DefaultSliceLoaderPtr = std::shared_ptr<DefaultSliceLoader>;
18
19 /// A singleton SliceLoader that the generated code uses to register factories for classes and exceptions.
20 class ICE_API DefaultSliceLoader final : public Ice::SliceLoader
21 {
22 public:
23 /// Returns the singleton instance of DefaultSliceLoader.
24 /// @return The single instance of DefaultSliceLoader.
25 static DefaultSliceLoaderPtr instance();
26
27 ~DefaultSliceLoader() final;
28
29 [[nodiscard]] Ice::ValuePtr newClassInstance(std::string_view typeId) const final;
30 [[nodiscard]] std::exception_ptr newExceptionInstance(std::string_view typeId) const final;
31
32 template<class T, std::enable_if_t<std::is_base_of_v<Ice::Value, T>, bool> = true> void addClass(int compactId)
33 {
34 std::lock_guard lock{_mutex};
35 auto p = _classFactories.find(T::ice_staticId());
36 if (p == _classFactories.end())
37 {
38 _classFactories[T::ice_staticId()] = {[] { return std::make_shared<T>(); }, 1};
39 }
40 else
41 {
42 p->second.second++;
43 }
44
45 if (compactId != -1)
46 {
47 std::string compactIdStr{std::to_string(compactId)};
48 p = _classFactories.find(compactIdStr);
49 if (p == _classFactories.end())
50 {
51 _classFactories[compactIdStr] = {[] { return std::make_shared<T>(); }, 1};
52 }
53 else
54 {
55 p->second.second++;
56 }
57 }
58 }
59
60 void removeClass(std::string_view typeId, int compactId)
61 {
62 std::lock_guard lock{_mutex};
63 auto p = _classFactories.find(typeId);
64 if (p != _classFactories.end())
65 {
66 if (--p->second.second == 0)
67 {
68 _classFactories.erase(p);
69 }
70 }
71
72 if (compactId != -1)
73 {
74 std::string compactIdStr{std::to_string(compactId)};
75 p = _classFactories.find(compactIdStr);
76 if (p != _classFactories.end())
77 {
78 if (--p->second.second == 0)
79 {
80 _classFactories.erase(p);
81 }
82 }
83 }
84 }
85
86 template<class T, std::enable_if_t<std::is_base_of_v<Ice::UserException, T>, bool> = true> void addException()
87 {
88 std::lock_guard lock{_mutex};
89 auto p = _exceptionFactories.find(T::ice_staticId());
90 if (p == _exceptionFactories.end())
91 {
92 _exceptionFactories[T::ice_staticId()] = {[] { return std::make_exception_ptr(T{}); }, 1};
93 }
94 else
95 {
96 p->second.second++;
97 }
98 }
99
100 void removeException(std::string_view typeId)
101 {
102 std::lock_guard lock{_mutex};
103 auto p = _exceptionFactories.find(typeId);
104 if (p != _exceptionFactories.end())
105 {
106 if (--p->second.second == 0)
107 {
108 _exceptionFactories.erase(p);
109 }
110 }
111 }
112
113 private:
114 using ClassFactory = std::function<Ice::ValuePtr()>;
115 using ExceptionFactory = std::function<std::exception_ptr()>;
116
117 DefaultSliceLoader() = default;
118
119 mutable std::mutex _mutex;
120
121 std::map<std::string, std::pair<ClassFactory, int>, std::less<>> _classFactories;
122 std::map<std::string, std::pair<ExceptionFactory, int>, std::less<>> _exceptionFactories;
123 };
124
125 template<class T> class ClassInit
126 {
127 public:
128 explicit ClassInit(int compactId = -1) noexcept : _typeId(T::ice_staticId()), _compactId(compactId)
129 {
130 DefaultSliceLoader::instance()->addClass<T>(compactId);
131 }
132
133 ~ClassInit() { DefaultSliceLoader::instance()->removeClass(_typeId, _compactId); }
134
135 private:
136 const char* _typeId;
137 int _compactId;
138 };
139
140 template<class T> class ExceptionInit
141 {
142 public:
143 ExceptionInit() noexcept : _typeId(T::ice_staticId()) { DefaultSliceLoader::instance()->addException<T>(); }
144 ~ExceptionInit() { DefaultSliceLoader::instance()->removeException(_typeId); }
145
146 private:
147 const char* _typeId;
148 };
149}
150
151#endif
std::shared_ptr< Value > ValuePtr
A shared pointer to a Value.
Definition ValueF.h:13