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