CodePorting.Translator Cs2Cpp
CodePorting.Translator.Cs2Cpp.Framework
multicast_delegate.h
1
3#ifndef _aspose_system_multicast_delegate_h_
4#define _aspose_system_multicast_delegate_h_
5
6#include "delegate.h"
7#include "shared_ptr.h"
8#include "exceptions.h"
9#include "system/details/delegate_holding_variables.h"
10#include <list>
11#include <functional>
12#include <algorithm>
13#include <type_traits>
14#include <utility>
15
16#define ASPOSE_REMOVE_EMPTY_CALLBACKS
17
18#ifdef ASPOSE_THREADSAFE_DELEGATES
19#include <mutex>
20#endif
21
22namespace System
23{
24 class IAsyncResult;
25
27 template<class Unused>
28 class MulticastDelegate;
30
31 using AsyncCallback = MulticastDelegate<void(SharedPtr<IAsyncResult>)>;
32
35 {
38 : TypeInfoPtr(u"System::MulticastDelegate")
39 {}
40 };
41
93 template <class ReturnType, class... ArgumentTypes>
94 class ASPOSECPP_SHARED_CLASS MulticastDelegate<ReturnType(ArgumentTypes...)> : public Details::DelegateHoldingVariables
95 {
96 private:
98
99 public:
101 using Callback = Delegate<ReturnType(ArgumentTypes...)>;
102
105 {
106 m_callbacks = std::make_shared<const std::list<Callback>>();
107 }
108
111 {}
112
114 MulticastDelegate(std::nullptr_t) : MulticastDelegate()
115 {}
116
119 MulticastDelegate(const MulticastDelegate& o)
120 : Details::DelegateHoldingVariables(o)
121 , m_callbacks(o.m_callbacks)
122 {}
123
126 MulticastDelegate& operator=(const MulticastDelegate& o)
127 {
128 if ( this == &o )
129 return *this;
130
131#ifdef ASPOSE_THREADSAFE_DELEGATES
132 std::lock(m_guard, o.m_guard);
133 std::lock_guard<std::recursive_mutex> l1( m_guard, std::adopt_lock );
134 std::lock_guard<std::recursive_mutex> l2(o.m_guard, std::adopt_lock);
135#endif
136 m_callbacks = o.m_callbacks;
137 Details::DelegateHoldingVariables::operator = (o);
138 return *this;
139 }
140
141 // movable
144 MulticastDelegate(MulticastDelegate&& o) noexcept
145 : Details::DelegateHoldingVariables(o)
146 , m_callbacks(std::move(o.m_callbacks))
147 {}
148
151 MulticastDelegate& operator=(MulticastDelegate&& o) noexcept
152 {
153 m_callbacks = std::move(o.m_callbacks);
154 Details::DelegateHoldingVariables::operator = (std::move(o));
155 return *this;
156 }
157
160 MulticastDelegate(Callback&& initial) : MulticastDelegate()
161 {
162 mutable_list()->push_back(std::move(initial));
163 }
164
168 template <class T, typename = decltype(Callback(std::declval<T>()))>
169 MulticastDelegate(T arg) : MulticastDelegate(Callback(arg))
170 {
171 }
172
175 MulticastDelegate(std::function<ReturnType(ArgumentTypes...)> arg) : MulticastDelegate(Callback(arg))
176 {
177 }
178
181 bool empty() const
182 {
183#ifdef ASPOSE_THREADSAFE_DELEGATES
184 std::lock_guard<std::recursive_mutex> lock(m_guard);
185#endif
186
187#ifdef ASPOSE_REMOVE_EMPTY_CALLBACKS
188 bool res = true;
189 if (m_callbacks)
190 {
191 for (auto it = m_callbacks->begin(); it != m_callbacks->end(); ++it)
192 res &= it->Empty();
193 }
194 return res;
195#else
196 return m_callbacks->empty();
197#endif
198 }
199
202 bool IsNull() const { return empty(); }
203
204 const TypeInfo& GetType() const
205 {
206 return Type();
207 }
208
210 {
211 return GetType().ToString();
212 }
213
214 int GetHashCode() const
215 {
216#ifdef ASPOSE_THREADSAFE_DELEGATES
217 std::lock_guard<std::recursive_mutex> lock(m_guard);
218#endif
219 return System::GetHashCode(m_callbacks.get());
220 }
221
222 bool Equals(const MulticastDelegate& other)
223 {
224 return *this == other;
225 }
226
229 bool operator==(const std::nullptr_t&) const
230 {
231 return empty();
232 }
233
236 bool operator!=(const std::nullptr_t&) const
237 {
238 return !operator==(nullptr);
239 }
240
244 MulticastDelegate& connect(Callback callback)
245 {
246#ifdef ASPOSE_THREADSAFE_DELEGATES
247 std::lock_guard<std::recursive_mutex> lock(m_guard);
248#endif
249
250 mutable_list()->push_back(std::move(callback));
251
252 return *this;
253 }
254
260 template <class R, class... Args>
261 MulticastDelegate& connect(std::function<R(Args...)> f)
262 {
263 return connect(Callback(f));
264 }
265
269 MulticastDelegate& connect(MulticastDelegate& other)
270 {
271 if (other.m_callbacks)
272 for (auto &callback : *other.m_callbacks)
273 connect(callback);
274 return *this;
275 }
276
283 template <class MemberType, class ClassType>
284 MulticastDelegate& connect(MemberType ClassType::* member, ClassType * obj)
285 {
286 CODEPORTING_DEBUG_ASSERT( obj != nullptr );
287 return connect(Callback(member, obj));
288 }
289
296 template <class MemberType, class ClassType>
297 MulticastDelegate& connect(MemberType ClassType::* member, const SharedPtr<ClassType> & obj)
298 {
299 CODEPORTING_DEBUG_ASSERT(obj != nullptr);
300 return connect(Callback(member, obj));
301 }
302
306 MulticastDelegate& operator +=(Callback callback)
307 {
308 return connect(std::move(callback));
309 }
310
314 MulticastDelegate& disconnect(Callback callback)
315 {
316#ifdef ASPOSE_THREADSAFE_DELEGATES
317 std::lock_guard<std::recursive_mutex> lock(m_guard);
318#endif
319 auto callbacks = mutable_list();
320 auto it = std::find_if(callbacks->rbegin(), callbacks->rend(), [&](const Callback& c){return callback == c;});
321 if (it != callbacks->rend())
322 callbacks->erase(std::next(it).base());
323 return *this;
324 }
325
332 template <class MemberType, class ClassType>
333 MulticastDelegate& disconnect(MemberType ClassType::* member, ClassType * obj)
334 {
335 CODEPORTING_DEBUG_ASSERT(obj != nullptr);
336 return disconnect(Callback(member, obj));
337 }
338
345 template <class MemberType, class ClassType>
346 MulticastDelegate& disconnect(MemberType ClassType::* member, const SharedPtr<ClassType> & obj)
347 {
348 CODEPORTING_DEBUG_ASSERT(obj != nullptr);
349 return disconnect(Callback(member, obj));
350 }
351
355 MulticastDelegate& disconnect(MulticastDelegate& other)
356 {
357 if (other.m_callbacks)
358 {
359#ifdef ASPOSE_THREADSAFE_DELEGATES
360 std::lock(m_guard, o.m_guard);
361 std::lock_guard<std::recursive_mutex> l1(m_guard, std::adopt_lock);
362 std::lock_guard<std::recursive_mutex> l2(o.m_guard, std::adopt_lock);
363#endif
364 for (auto &callback : *other.m_callbacks)
365 disconnect(callback);
366 }
367 return *this;
368 }
369
373 MulticastDelegate& operator -=(Callback callback)
374 {
375 return disconnect(std::move(callback));
376 }
377
381 bool operator == (const MulticastDelegate& other) const
382 {
383 CODEPORTING_DEBUG_ASSERT(m_callbacks != nullptr && other.m_callbacks != nullptr);
384
385 // If both delegates point to same callback list - they are equal for sure
386 if (m_callbacks == other.m_callbacks)
387 return true;
388
389 // Then compare all callbacks one for another
390 return *m_callbacks == *other.m_callbacks;
391 }
392
396 bool operator != (const MulticastDelegate& other) const
397 {
398 return !operator == (other);
399 }
400
403 MulticastDelegate& disconnect_all_slots()
404 {
405#ifdef ASPOSE_THREADSAFE_DELEGATES
406 std::lock_guard<std::recursive_mutex> lock(m_guard);
407#endif
408 mutable_list()->clear();
409
410 return *this;
411 }
412
415 {
416 if (m_callbacks && !m_callbacks->empty())
417 {
418 // We don't need to get unique callbacks here, because even shared callbacks, if empty, are subject to cleanup.
419 auto* mutable_callbacks = const_cast<std::list<Callback>*>(m_callbacks.get());
420
421 for (auto it = mutable_callbacks->begin(); it != mutable_callbacks->end();)
422 {
423 if (it->Empty())
424 it = mutable_callbacks->erase(it);
425 else
426 ++it;
427 }
428 }
429 }
430
434 ReturnType invoke(ArgumentTypes... args) const
435 {
436#ifdef ASPOSE_THREADSAFE_DELEGATES
437 std::lock_guard<std::recursive_mutex> lock(m_guard);
438#endif
439
440#ifdef ASPOSE_REMOVE_EMPTY_CALLBACKS
441 remove_empty_callbacks();
442#endif
443 if (m_callbacks && !m_callbacks->empty())
444 {
445 auto callbacks_copy = m_callbacks; // we must save the current callbacks list in case it will be changed during the call
446 auto last = std::prev(callbacks_copy->end()); // always valid, m_callbacks is not empty
447 for (auto it = callbacks_copy->begin(); it != last; ++it)
448 (*it)(args...); // ignore result!
449
450 return (*last)(args...);
451 }
452
453 throw NullReferenceException(u"MulticastDelegate: Object reference not set to an instance of an object.");
454 }
455
459 ReturnType operator()(ArgumentTypes... args) const
460 {
461 return invoke(args...);
462 }
463
465 static const TypeInfo& Type()
466 {
467 return *static_holder<ThisTypeInfo>();
468 }
469
470
473 template <typename CallbackArgumentType>
474 SharedPtr<IAsyncResult> BeginInvoke(ArgumentTypes... args, const AsyncCallback& member, const CallbackArgumentType& obj)
475 {
476 throw System::NotImplementedException(ASPOSE_CURRENT_FUNCTION);
477 }
478
482 {
483 throw System::NotImplementedException(ASPOSE_CURRENT_FUNCTION);
484 }
485
486#if defined(ASPOSE_GET_SHARED_MEMBERS) || defined(__DBG_FOR_EACH_MEMBER)
488 std::shared_ptr<Details::HeldVariables> GetHeldVariables() const
489 {
490 auto heldVariables = std::make_shared<Details::HeldVariables>();
491
492 heldVariables->CopyFrom(m_heldVariables);
493
494 if (m_callbacks && !m_callbacks->empty())
495 {
496 for (auto it = m_callbacks->cbegin(); it != m_callbacks->cend(); ++it)
497 {
498 heldVariables->CopyFrom(it->GetHeldVariables());
499 }
500 }
501
502 return heldVariables;
503 }
504#endif
505
506 private:
509 std::list<Callback>* mutable_list()
510 {
511 CODEPORTING_DEBUG_ASSERT(m_callbacks != nullptr);
512
513 if (m_callbacks.use_count() > 1)
514 m_callbacks = std::make_shared<std::list<Callback>>(*m_callbacks);
515
516 return const_cast<std::list<Callback>*>(m_callbacks.get());
517 }
518
520 mutable std::shared_ptr<const std::list<Callback>> m_callbacks;
521
522#ifdef ASPOSE_THREADSAFE_DELEGATES
524 mutable std::recursive_mutex m_guard;
525#endif
526 };
527
532 template <typename T>
533 MulticastDelegate<T> operator+(MulticastDelegate<T> lhv, MulticastDelegate<T> rhv)
534 {
535 return lhv.connect(rhv);
536 }
537
542 template <typename T>
543 MulticastDelegate<T> operator-(MulticastDelegate<T> lhv, MulticastDelegate<T> rhv)
544 {
545 return lhv.disconnect(rhv);
546 }
547
550 template <typename TTo> struct CastResult;
551
554 template <typename T>
555 struct ASPOSECPP_SHARED_CLASS CastResult<MulticastDelegate<T>>
556 {
558 typedef MulticastDelegate<T> type;
559 };
560
561 template <class T>
562 struct IsBoxable<MulticastDelegate<T>> : std::true_type
563 {
564 };
566
567} // namespace System
568#endif // _aspose_system_multicast_delegate_h_
Represents a pointer to a function, method or a function object. This type should be allocated on sta...
Definition: delegate.h:56
MulticastDelegate & connect(MulticastDelegate &other)
Adds the specified MulticastDelegate object to the delegate collection.
Definition: multicast_delegate.h:269
MulticastDelegate & disconnect(MemberType ClassType::*member, const SharedPtr< ClassType > &obj)
Removes the specified non-static method of the specified object from the delegate collection.
Definition: multicast_delegate.h:346
MulticastDelegate(MulticastDelegate &&o) noexcept
Moving constructor.
Definition: multicast_delegate.h:144
bool operator!=(const std::nullptr_t &) const
Determines whether the delegate collection is not empty.
Definition: multicast_delegate.h:236
bool empty() const
Determines whether the delegate collection is empty.
Definition: multicast_delegate.h:181
ReturnType operator()(ArgumentTypes... args) const
Invokes all delegates currently present in the delegates collection. Delegates are invoked in the sam...
Definition: multicast_delegate.h:459
MulticastDelegate & operator=(const MulticastDelegate &o)
Assigns the collection of delegates represented by the specified object to the current object....
Definition: multicast_delegate.h:126
bool IsNull() const
Determines whether the delegate collection is empty.
Definition: multicast_delegate.h:202
MulticastDelegate & disconnect(MulticastDelegate &other)
Removes the specified MulticastDelegate object from the delegate collection.
Definition: multicast_delegate.h:355
MulticastDelegate & operator=(MulticastDelegate &&o) noexcept
Moving assignment operator.
Definition: multicast_delegate.h:151
MulticastDelegate & connect(MemberType ClassType::*member, const SharedPtr< ClassType > &obj)
Adds the specified non-static method of the specified object to the delegate collection.
Definition: multicast_delegate.h:297
MulticastDelegate & disconnect(Callback callback)
Removes the specified delegate from the delegate collection.
Definition: multicast_delegate.h:314
MulticastDelegate & disconnect(MemberType ClassType::*member, ClassType *obj)
Removes the specified non-static method of the specified object from the delegate collection.
Definition: multicast_delegate.h:333
MulticastDelegate(const MulticastDelegate &o)
Performs a shallow copy of the delegate collection.
Definition: multicast_delegate.h:119
MulticastDelegate & connect(MemberType ClassType::*member, ClassType *obj)
Adds the specified non-static method of the specified object to the delegate collection.
Definition: multicast_delegate.h:284
ReturnType EndInvoke(const SharedPtr< IAsyncResult > &)
NOT IMPLEMENTED.
Definition: multicast_delegate.h:481
MulticastDelegate(Callback &&initial)
Constructs an instance and puts the specified delegate to the delegates collection.
Definition: multicast_delegate.h:160
String ToString() const
Definition: multicast_delegate.h:209
MulticastDelegate(T arg)
Constructs an instance and puts the specified value to the delegates collection.
Definition: multicast_delegate.h:169
ReturnType invoke(ArgumentTypes... args) const
Invokes all delegates currently present in the delegates collection. Delegates are invoked in the sam...
Definition: multicast_delegate.h:434
static const TypeInfo & Type()
Returns a reference to the TypeInfo object representing the MulticastDelegate class type information.
Definition: multicast_delegate.h:465
MulticastDelegate & connect(std::function< R(Args...)> f)
Adds the specified function object to the delegate collection. The function object is converted to th...
Definition: multicast_delegate.h:261
MulticastDelegate & disconnect_all_slots()
Removes all delegates from the delegate collection.
Definition: multicast_delegate.h:403
~MulticastDelegate()
Destructor.
Definition: multicast_delegate.h:110
MulticastDelegate & connect(Callback callback)
Adds the specified delegate to the collection.
Definition: multicast_delegate.h:244
MulticastDelegate(std::function< ReturnType(ArgumentTypes...)> arg)
Constructs an instance and puts the specified value to the delegates collection.
Definition: multicast_delegate.h:175
const TypeInfo & GetType() const
Definition: multicast_delegate.h:204
MulticastDelegate()
Constructs an empty collection.
Definition: multicast_delegate.h:104
bool Equals(const MulticastDelegate &other)
Definition: multicast_delegate.h:222
int GetHashCode() const
Definition: multicast_delegate.h:214
void remove_empty_callbacks() const
Cleans out contained callbacks that are empty (not actually calling anything).
Definition: multicast_delegate.h:414
bool operator==(const std::nullptr_t &) const
Determines whether the delegate collection is empty.
Definition: multicast_delegate.h:229
MulticastDelegate(std::nullptr_t)
Equivalent to defalt constructor.
Definition: multicast_delegate.h:114
SharedPtr< IAsyncResult > BeginInvoke(ArgumentTypes... args, const AsyncCallback &member, const CallbackArgumentType &obj)
NOT IMPLEMENTED.
Definition: multicast_delegate.h:474
Pointer class to wrap types being allocated on heap. Use it to manage memory for classes inheriting O...
Definition: smart_ptr.h:180
String class used across the library. Is a substitute for C# System.String when translating code....
Definition: string.h:122
String ToString() const
Wrapper for handling String class in contexts where ToString() is being called on value type objects.
Definition: string.h:504
Represents a particular type and provides information about it.
Definition: type_info.h:109
Definition: db_command.h:9
System::MulticastDelegate< void(SharedPtr< IAsyncResult >)> AsyncCallback
A delegate type that represents a method to be called when asynchronous operation completes.
Definition: async_callback.h:13
bool operator!=(ArraySegment< T > a, ArraySegment< T > b)
Definition: array_segment.h:156
Decimal operator+(const T &x, const Decimal &d)
Returns a new instance of Decimal class that represents a value that is a sum of the specified value ...
Definition: decimal.h:542
auto operator-(DayOfWeek a, DayOfWeek b)
Calculates the number of days between two days of week.
Definition: day_of_week.h:25
std::enable_if< std::is_scalar< T >::value, int >::type GetHashCode(const T &obj)
Returns a hash code for the specified scalar value.
Definition: get_hash_code.h:21
bool operator==(ArraySegment< T > a, ArraySegment< T > b)
Definition: array_segment.h:150
Represents a pointer to TypeInfo object that contains information about MulticastDelegate class.
Definition: multicast_delegate.h:35
MulticastDelegateTypeInfo()
Constructs an instance of MulticastDelegateTypeInfo class.
Definition: multicast_delegate.h:37
Wrapper for a pointer to an instance of TypeInfo class. This type should be allocated on stack and pa...
Definition: type_info.h:72