39 #ifndef CGU_SHARED_HANDLE_H
40 #define CGU_SHARED_HANDLE_H
56 #ifdef CGU_SHARED_LOCK_HANDLE_USE_MUTEX
251 std::free(const_cast<void*>(obj));
270 g_free(const_cast<void*>(obj));
313 g_slice_free1(
sizeof(*obj), (
void*)obj);
378 template <
class U>
void destroy(U& obj) {obj.~U();}
382 g_slice_free1(
sizeof(*obj), (
void*)obj);
421 g_slice_free1(block_size, const_cast<void*>(obj));
524 virtual const char*
what()
const throw() {
return "SharedHandleError\n";}
537 namespace SharedHandleAllocFail {
541 template <
class T,
class Dealloc = StandardArrayDelete<T>>
class SharedHandle {
545 #ifndef DOXYGEN_PARSING
547 unsigned int* ref_count_p;
553 if (!ref_items.ref_count_p)
return;
554 --(*ref_items.ref_count_p);
555 if (*ref_items.ref_count_p == 0) {
556 #ifdef CGU_USE_GLIB_MEMORY_SLICES_NO_COMPAT
557 g_slice_free(
unsigned int, ref_items.ref_count_p);
559 delete ref_items.ref_count_p;
561 deleter(ref_items.obj);
565 void reference() noexcept {
566 if (!ref_items.ref_count_p)
return;
567 ++(*ref_items.ref_count_p);
591 if ((ref_items.obj = ptr)) {
592 #ifdef CGU_USE_GLIB_MEMORY_SLICES_NO_COMPAT
593 ref_items.ref_count_p = g_slice_new(
unsigned int);
594 *ref_items.ref_count_p = 1;
597 ref_items.ref_count_p =
new unsigned int(1);
607 else ref_items.ref_count_p = 0;
639 if ((ref_items.obj = ptr)) {
640 #ifdef CGU_USE_GLIB_MEMORY_SLICES_NO_COMPAT
641 ref_items.ref_count_p = g_slice_new(
unsigned int);
642 *ref_items.ref_count_p = 1;
645 ref_items.ref_count_p =
new unsigned int(1);
647 catch (std::bad_alloc&) {
652 else ref_items.ref_count_p = 0;
728 ref_items = sh_hand.ref_items;
737 ref_items = sh_hand.ref_items;
738 sh_hand.ref_items.ref_count_p = 0;
739 sh_hand.ref_items.obj = 0;
762 T
get()
const noexcept {
return ref_items.obj;}
769 operator T() const noexcept {
return ref_items.obj;}
776 unsigned int get_refcount() const noexcept {
return (ref_items.ref_count_p) ? *ref_items.ref_count_p : 0;}
825 template <
class T,
class Dealloc = StandardArrayDelete<T>>
class ScopedHandle {
861 reset(sc_hand.release());
886 if (ptr) deleter(ptr);
895 T
release() noexcept {T tmp = obj; obj = 0;
return tmp;}
902 T
get()
const noexcept {
return obj;}
909 operator T() const noexcept {
return obj;}
1056 #ifndef DOXYGEN_PARSING
1058 #ifdef CGU_SHARED_LOCK_HANDLE_USE_MUTEX
1060 unsigned int* ref_count_p;
1071 void unreference() {
1076 if (!ref_items.ref_count_p)
return;
1077 #ifdef CGU_SHARED_LOCK_HANDLE_USE_MUTEX
1078 ref_items.mutex_p->
lock();
1079 --(*ref_items.ref_count_p);
1080 if (*ref_items.ref_count_p == 0) {
1081 # ifdef CGU_USE_GLIB_MEMORY_SLICES_NO_COMPAT
1082 g_slice_free(
unsigned int, ref_items.ref_count_p);
1084 delete ref_items.ref_count_p;
1086 ref_items.mutex_p->unlock();
1087 delete ref_items.mutex_p;
1088 deleter(ref_items.obj);
1090 else ref_items.mutex_p->unlock();
1092 if (g_atomic_int_dec_and_test(ref_items.ref_count_p)) {
1093 # ifdef CGU_USE_GLIB_MEMORY_SLICES_NO_COMPAT
1094 g_slice_free(gint, ref_items.ref_count_p);
1096 delete ref_items.ref_count_p;
1098 deleter(ref_items.obj);
1105 void reference() noexcept {
1110 if (!ref_items.ref_count_p)
return;
1111 #ifdef CGU_SHARED_LOCK_HANDLE_USE_MUTEX
1113 ++(*ref_items.ref_count_p);
1115 g_atomic_int_inc(ref_items.ref_count_p);
1149 if ((ref_items.obj = ptr)) {
1150 #ifdef CGU_SHARED_LOCK_HANDLE_USE_MUTEX
1160 # ifdef CGU_USE_GLIB_MEMORY_SLICES_NO_COMPAT
1161 ref_items.ref_count_p = g_slice_new(
unsigned int);
1162 *ref_items.ref_count_p = 1;
1165 ref_items.ref_count_p =
new unsigned int(1);
1168 delete ref_items.mutex_p;
1174 # ifdef CGU_USE_GLIB_MEMORY_SLICES_NO_COMPAT
1175 ref_items.ref_count_p = g_slice_new(gint);
1176 *ref_items.ref_count_p = 1;
1179 ref_items.ref_count_p =
new gint(1);
1191 #ifdef CGU_SHARED_LOCK_HANDLE_USE_MUTEX
1192 ref_items.mutex_p = 0;
1194 ref_items.ref_count_p = 0;
1237 if ((ref_items.obj = ptr)) {
1238 #ifdef CGU_SHARED_LOCK_HANDLE_USE_MUTEX
1242 catch (std::bad_alloc&) {
1248 # ifdef CGU_USE_GLIB_MEMORY_SLICES_NO_COMPAT
1249 ref_items.ref_count_p = g_slice_new(
unsigned int);
1250 *ref_items.ref_count_p = 1;
1253 ref_items.ref_count_p =
new unsigned int(1);
1255 catch (std::bad_alloc&) {
1256 delete ref_items.mutex_p;
1261 # ifdef CGU_USE_GLIB_MEMORY_SLICES_NO_COMPAT
1262 ref_items.ref_count_p = g_slice_new(gint);
1263 *ref_items.ref_count_p = 1;
1266 ref_items.ref_count_p =
new gint(1);
1268 catch (std::bad_alloc&) {
1275 #ifdef CGU_SHARED_LOCK_HANDLE_USE_MUTEX
1276 ref_items.mutex_p = 0;
1278 ref_items.ref_count_p = 0;
1386 ref_items = sh_hand.ref_items;
1395 ref_items = sh_hand.ref_items;
1396 #ifdef CGU_SHARED_LOCK_HANDLE_USE_MUTEX
1397 sh_hand.ref_items.mutex_p = 0;
1399 sh_hand.ref_items.ref_count_p = 0;
1400 sh_hand.ref_items.obj = 0;
1413 std::swap(ref_items, sh_hand.ref_items);
1422 T
get()
const noexcept {
return ref_items.obj;}
1429 operator T() const noexcept {
return ref_items.obj;}
1441 if (!ref_items.ref_count_p)
return 0;
1442 #ifdef CGU_SHARED_LOCK_HANDLE_USE_MUTEX
1444 return *ref_items.ref_count_p;
1446 return g_atomic_int_get(ref_items.ref_count_p);
1457 #if defined(CGU_USE_SMART_PTR_COMPARISON) || defined(DOXYGEN_PARSING)
1469 template <
class T,
class Dealloc>
1471 return (s1.get() == s2.get());
1482 template <
class T,
class Dealloc>
1501 template <
class T,
class Dealloc>
1503 return std::less<T>()(s1.get(), s2.get());
1514 template <
class T,
class Dealloc>
1516 return (s1.get() == s2.get());
1527 template <
class T,
class Dealloc>
1541 template <
class T,
class Dealloc>
1543 return std::less<T>()(s1.get(), s2.get());
1546 #endif // CGU_USE_SMART_PTR_COMPARISON
1553 #if defined(CGU_USE_SMART_PTR_COMPARISON) && !defined(DOXYGEN_PARSING)
1557 template <
class T,
class Dealloc>
1558 struct hash<Cgu::SharedHandle<T, Dealloc>> {
1559 typedef std::size_t result_type;
1561 result_type operator()(
const argument_type& s)
const {
1568 template <
class T,
class Dealloc>
1569 struct hash<Cgu::SharedLockHandle<T, Dealloc>> {
1570 typedef std::size_t result_type;
1572 result_type operator()(
const argument_type& s)
const {
1580 #endif // CGU_USE_SMART_PTR_COMPARISON