c++-gtk-utils: gobj_handle.h Source File

c++-gtk-utils

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

gobj_handle.h
Go to the documentation of this file.
1 /* Copyright (C) 2005 to 2013 Chris Vine
2
3 The library comprised in this file or of which this file is part is
4 distributed by Chris Vine under the GNU Lesser General Public
5 License as follows:
6
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public License
9 as published by the Free Software Foundation; either version 2.1 of
10 the License, or (at your option) any later version.
11
12 This library is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License, version 2.1, for more details.
16
17 You should have received a copy of the GNU Lesser General Public
18 License, version 2.1, along with this library (see the file LGPL.TXT
19 which came with this source code package in the c++-gtk-utils
20 sub-directory); if not, write to the Free Software Foundation, Inc.,
21 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22
23 However, it is not intended that the object code of a program whose
24 source code instantiates a template from this file or uses macros or
25 inline functions (of any length) should by reason only of that
26 instantiation or use be subject to the restrictions of use in the GNU
27 Lesser General Public License. With that in mind, the words "and
28 macros, inline functions and instantiations of templates (of any
29 length)" shall be treated as substituted for the words "and small
30 macros and small inline functions (ten lines or less in length)" in
31 the fourth paragraph of section 5 of that licence. This does not
32 affect any other reason why object code may be subject to the
33 restrictions in that licence (nor for the avoidance of doubt does it
34 affect the application of section 2 of that licence to modifications
35 of the source code in this file).
36
37 */
38
39 #ifndef CGU_GOBJ_HANDLE_H
40 #define CGU_GOBJ_HANDLE_H
41
42 #include <exception>
43 #include <functional> // for std::less and std::hash<T*>
44 #include <cstddef> // for std::size_t
45
46 #include <glib-object.h>
47
48 #include <c++-gtk-utils/cgu_config.h>
49
50 /**
51 * @addtogroup handles handles and smart pointers
52 */
53
54 namespace Cgu {
55
56 /**
57 * @class GobjHandle gobj_handle.h c++-gtk-utils/gobj_handle.h
58 * @brief This is a handle for managing the reference count of
59 * GObjects.
60 * @ingroup handles
61 * @sa MainWidgetBase GobjWeakHandle
62 *
63 * This is a class which manages the reference count of GObjects. It
64 * does not maintain its own reference count, but interfaces with that
65 * kept by the glib object system.
66 *
67 * GobjHandles are most useful to manage GObjects which are not also
68 * GtkWidgets or GInitiallyUnowned objects - GtkWidgets and
69 * GInitiallyUnowned objects have initial floating references which
70 * will result in them being automatically managed by the container in
71 * which they are held. Nonetheless, GobjHandles can be used to hold
72 * GtkWidgets and GInitiallyUnowned objects, as the constructor of a
73 * GobjHandle which takes a pointer will automatically take ownership
74 * of a newly created GtkWidget or GInitiallyUnowned object, by
75 * calling g_object_ref_sink(). Plain GObjects do not need to be sunk
76 * to be owned by the GobjHandle.
77 *
78 * Note that g_object_ref_sink() is not called by the constructor
79 * taking a pointer if the floating reference has already been sunk,
80 * so if that constructor is passed an object already owned by a GTK
81 * container it will be necessary to call g_object_ref() on it
82 * explicitly. This behaviour will ensure that the handle behaves the
83 * same whether it is holding a plain GObject, or it is holding a
84 * GInitiallyUnowned/GtkWidget object. Generally however, where an
85 * object is already owned by a container, the object should be passed
86 * by another handle - ie by the copy constructor (or by the
87 * assignment operator), as those always increment the reference count
88 * automatically.
89 *
90 * In other words, invoke the constructor taking a pointer only with a
91 * newly created object (whether a GObject, GInitiallyUnowned or
92 * GtkWidget object), and everything else will take care of itself. In
93 * this respect, GobjHandles work the same way as conventional shared
94 * pointer implementations managing objects allocated on free store.
95 * The same applies to the reset() method. (Care is required however
96 * if initializing a Cgu::GobjHandle with a widget or GObject object
97 * obtained from GtkBuilder, since these are not "newly created" in
98 * this sense. It is necessary to call g_object_ref() by hand in that
99 * case, since GtkBuilder does not by itself pass ownership of any
100 * objects it creates.)
101 *
102 * Because any GTK containers themselves increment the reference
103 * count of a GObject or GtkWidget where they need to take ownership,
104 * an already-managed object held by a GobjHandle can safely be passed
105 * by pointer to a GTK container, and that is one of the intended
106 * usages. For that purpose, although the class has operator*() and
107 * operator->() dereferencing operators, and so has normal smart
108 * pointer functionality, as it is intended for use with the normal C
109 * GObject/pango/GTK interfaces, ordinary use would involve passing
110 * the handle to a function taking a pointer by means of the
111 * operatorT*() type conversion operator (which returns the underlying
112 * pointer), or by explicitly calling the get() method to obtain the
113 * underlying pointer.
114 *
115 * The principal intended usage of GobjHandle is to automatically
116 * handle GObject reference counts and therefore to make GObjects
117 * exception-safe, but they also permit GObjects/GtkWidgets to be kept
118 * in standard C++ containers.
119 *
120 * As of glib-2.8, g_object_ref() and g_object_unref() are thread
121 * safe, so with glib-2.8 or greater there can be different GobjHandle
122 * instances in different threads referencing the same GObject object.
123 * Of course, if that is done, this does not affect the need (or
124 * otherwise) in the particular use in question to lock anything other
125 * than the reference count - say when accessing the referenced object
126 * itself in different threads.
127 *
128 * Typical usage might be, for example, as follows:
129 *
130 * @code
131 * using namespace Cgu;
132 * GobjHandle<GtkListStore> store(gtk_list_store_new(1, G_TYPE_STRING));
133 *
134 * [ ... fill the list store ... ]
135 *
136 * GobjHandle<GtkWidget> view(gtk_tree_view_new_with_model(GTK_TREE_MODEL(store.get()));
137 * // 'view' will take sole ownership of the list store when 'store' goes out of scope, or
138 * // 'store' could be kept alive so that the list store will survive removal from the view
139 *
140 * [ ... set up an interface including a GtkVBox 'vbox' which will hold the tree view ... ]
141 *
142 * gtk_container_add(GTK_CONTAINER(vbox), view);
143 * // 'vbox' will take sole ownership of the tree view when 'view' goes out of scope, or
144 * // 'view' could be kept alive so that the tree view will survive removal from the vbox
145 * @endcode
146 */
147
148 template <class T> class GobjHandle {
149
150 T* obj_p;
151
152 void unreference() {
153 if (obj_p) g_object_unref(obj_p);
154 }
155
156 void reference() noexcept {
157 if (obj_p) g_object_ref(obj_p);
158 }
159
160 public:
161
162 /**
163 * The constructor does not throw. g_object_ref_sink() is called if
164 * the managed object has a floating reference.
165 * @param ptr The object which the GobjHandle is to manage (if any).
166 * @note The object passed should not normally be already owned by a
167 * GTK container or managed by any other GobjHandle object. If it
168 * is, g_object_ref() must be called explicitly by the user code.
169 */
170 explicit GobjHandle(T* ptr = 0) noexcept {
171 obj_p = ptr;
172
173 // if an object with a floating reference has been passed to this constructor,
174 // take ownership of it
175 if (ptr && g_object_is_floating(ptr)) {
176 g_object_ref_sink(ptr);
177 }
178 }
179
180 /**
181 * Causes the handle to cease to manage its managed object (if any)
182 * and decrements its reference count, so destroying it if the
183 * reference count thereby becomes 0. If the argument passed is not
184 * NULL, the handle will manage the new object passed and
185 * g_object_ref_sink() is called if the new object has a floating
186 * reference. This method does not throw (unless this method
187 * destroys a sub-classed GObject which has a member object whose
188 * destructor throws).
189 * @param ptr NULL (the default), or a new object to manage.
190 * @note The new object passed should not normally be already owned
191 * by a GTK container or managed by any other GobjHandle object. If
192 * it is, g_object_ref() must be called explicitly by the user code.
193 */
194 void reset(T* ptr = 0) {
195
196 unreference();
197 obj_p = ptr;
198
199 // if an object with a floating reference has been passed to this method,
200 // take ownership of it
201 if (ptr && g_object_is_floating(ptr)) {
202 g_object_ref_sink(ptr);
203 }
204 }
205
206 /**
207 * The copy constructor does not throw. It increments the reference
208 * count of the managed object.
209 * @param gobj The handle to be copied.
210 */
211 GobjHandle(const GobjHandle& gobj) noexcept {
212 obj_p = gobj.obj_p;
213 reference();
214 }
215
216 /**
217 * The move constructor does not throw. It has move semantics.
218 * @param gobj The handle to be moved.
219 */
220 GobjHandle(GobjHandle&& gobj) noexcept {
221 obj_p = gobj.obj_p;
222 gobj.obj_p = 0;
223 }
224
225 // We don't have a constructor for GobjHandle taking a GobjWeakHandle
226 // object. If we did that, we would have to remove the GobjWeakHandle
227 // constructor taking a pointer so we know that its tracked object
228 // always has an owner when initialising a new GobjHandle with the
229 // GobjWeakHandle, so we can in turn know we can increase the reference
230 // count when initialising the GobjHandle. However, removing that
231 // constructor would be inconsistent with one of the purposes of having
232 // a GobjWeakHandle class. For the same reason, we don't have an
233 // assignment operator for GobjHandle taking such an object.
234 /**
235 * This method decrements the reference count of the former managed
236 * object (if any), so destroying it if the reference count thereby
237 * becomes 0, and increments the reference count of the new managed
238 * object. This method does not throw (unless this method destroys a
239 * sub-classed GObject which has a member object whose destructor
240 * throws).
241 * @param gobj The assignor.
242 * @return The GobjHandle object after assignment.
243 */
244 GobjHandle& operator=(const GobjHandle& gobj) {
245
246 // check whether we are already referencing this object -
247 // if so make this a null op. This will also deal with
248 // self-assignment
249 if (obj_p != gobj.obj_p) {
250
251 // first unreference any object referenced by this handle
252 unreference();
253
254 // now inherit the GObject from the assigning handle
255 // and reference it
256 obj_p = gobj.obj_p;
257 reference();
258 }
259 return *this;
260 }
261
262 /**
263 * This method decrements the reference count of the former managed
264 * object (if any), so destroying it if the reference count thereby
265 * becomes 0, and has move semantics with respect to the new managed
266 * object. This method does not throw (unless this method destroys a
267 * sub-classed GObject which has a member object whose destructor
268 * throws).
269 * @param gobj The handle to be moved.
270 * @return The GobjHandle object after the move operation.
271 */
272 GobjHandle& operator=(GobjHandle&& gobj) {
273
274 // check for self-assignment
275 if (this != &gobj) {
276
277 // first unreference any object referenced by this handle
278 unreference();
279
280 // now inherit the GObject from the moving handle
281 obj_p = gobj.obj_p;
282 gobj.obj_p = 0;
283 }
284 return *this;
285 }
286
287 /**
288 * This method does not throw.
289 * @return A pointer to the handled GObject (or NULL if none is
290 * handled).
291 */
292 T* get() const noexcept {return obj_p;}
293
294 /**
295 * This method does not throw.
296 * @return A reference to the handled GObject.
297 */
298 T& operator*() const noexcept {return *obj_p;}
299
300 /**
301 * This method does not throw.
302 * @return A pointer to the handled GObject (or NULL if none is
303 * handled).
304 */
305 T* operator->() const noexcept {return obj_p;}
306
307 /**
308 * This method does not throw.
309 * @return A pointer to the handled GObject (or NULL if none is
310 * handled).
311 */
312 operator T*() const noexcept {return obj_p;}
313
314 /**
315 * The destructor does not throw. It decrements the reference count
316 * of the managed object (if any), so destroying it if the reference
317 * count thereby becomes 0.
318 */
319 ~GobjHandle() {unreference();}
320 };
321
322 /**
323 * @class GobjWeakHandle gobj_handle.h c++-gtk-utils/gobj_handle.h
324 * @brief This is a handle for managing weak references to GObjects.
325 * @ingroup handles
326 * @sa GobjHandle
327 *
328 * This class tracks a GObject, so that if that GObject no longer
329 * exists then operator bool() or the valid() method will return
330 * false, but does not take a strong reference by incrementing the
331 * reference count to the GObject and so take ownership of it. It has
332 * two main use areas: first, in order to break reference cycles that
333 * may otherwise arise if two classes would otherwise hold strong
334 * references to each other. Secondly, to manage a pointer to a
335 * GObject returned by a GTK getter function where ownership is not
336 * passed (that is, where the user is not expected to call
337 * g_object_unref() when finished with the return value). A typical
338 * example of this is the GtkTreeSelection object returned by
339 * gtk_tree_view_get_selection(). The GtkTreeSelection object is part
340 * of the GtkTreeView's implemention and will become invalid as soon
341 * as the GtkTreeView object is finalized.
342 *
343 * As in the case of the GobjHandle class, although this class has
344 * operator*() and operator->() dereferencing operators, and so has
345 * normal smart pointer functionality, as it is intended for use with
346 * the normal C GObject/pango/GTK interfaces, ordinary use would
347 * involve passing the handle to a function taking a pointer by means
348 * of the operatorT*() type conversion operator (which returns the
349 * underlying pointer), or by explicitly calling the get() method to
350 * obtain the underlying pointer.
351 *
352 * Typical usage is as follows:
353 *
354 * @code
355 * using namespace Cgu;
356 * GobjWeakHandle<GtkTreeSelection> s(gtk_tree_view_get_selection(tree_view));
357 * gtk_tree_selection_set_mode(s, GTK_SELECTION_SINGLE);
358 * ...
359 *
360 * [some code blocks later]
361 * if (s) { // check that the GtkTreeSelection object still exists.
362 * GtkTreeIter iter;
363 * GtkTreeModel* model = 0;
364 * gtk_tree_selection_get_selected(s, &model, &iter);
365 * ...
366 * }
367 * else [report error];
368 * @endcode
369 *
370 * Or instead of an 'if' block, GobjWeakHandleError could be caught:
371 *
372 * @code
373 * using namespace Cgu;
374 * GobjWeakHandle<GtkTreeSelection> s(gtk_tree_view_get_selection(tree_view));
375 * gtk_tree_selection_set_mode(s, GTK_SELECTION_SINGLE);
376 * ...
377 *
378 * [some code blocks later]
379 * GtkTreeIter iter;
380 * GtkTreeModel* model = 0;
381 * try {
382 * gtk_tree_selection_get_selected(s, &model, &iter);
383 * ...
384 * }
385 * catch (GobjWeakHandleError&) {[report error]}
386 * @endcode
387 *
388 * @b Thread-safe @b use
389 *
390 * This class wraps
391 * g_object_add_weak_pointer()/g_object_remove_weak_pointer(), and as
392 * those GObject functions have practical limitations concerning
393 * thread-safe use, this class has the same practical limitations. As
394 * shown above, typical usage for a weak pointer 's' would be 'if (s)
395 * do_it(s)', but if the thread calling that sequence (thread A) were
396 * not the thread controlling the lifetime of the referenced GObject
397 * (thread B), then thread B may have destroyed the GObject between
398 * thread A testing 's' and then calling the referenced object. The
399 * same applies to the test leading to GobjWeakHandleError being
400 * thrown.
401 *
402 * In other words, in the GtkTreeSelection code example above, if the
403 * thread calling gtk_tree_selection_get_selected() were not the main
404 * GUI thread (which would anyway require the use of
405 * gdk_threads_enter()/gdk_threads_leave()), then the calling thread
406 * must ensure that the main GUI thread does not destroy the relevant
407 * tree view, and so the GtkTreeSelection object, from the beginning
408 * of the 'if' test to the end of the 'if' block, or for the duration
409 * of the try block. (This cannot be done just by incrementing the
410 * reference count of the tree view or the tree selection in the
411 * calling thread before the 'if' test or the try block is entered,
412 * because by the time the reference is incremented and the weak
413 * pointer tested, the tree view and tree selection may already be in
414 * their dispose functions but the tree selection's dispose function
415 * may not yet have reached the point of dispatching the callback
416 * NULLing the weak pointer. As a general design issue, it is usually
417 * best only to call GTK functions in one thread, and in order to
418 * make that straightforward, this library contains a number of
419 * classes and functions for inter-thread communication.)
420 */
421
422 struct GobjWeakHandleError: public std::exception {
423 virtual const char* what() const throw() {return "GobjWeakHandleError\n";}
424 };
425
426 template <class T> class GobjWeakHandle {
427
428 T* obj_p;
429
430 public:
431
432 /**
433 * This constructor does not throw.
434 * @param ptr The object which the GobjWeakHandle is to track (if any).
435 */
436 explicit GobjWeakHandle(T* ptr = 0) noexcept {
437 obj_p = ptr;
438 if (ptr) g_object_add_weak_pointer((GObject*)ptr,
439 (void**)&obj_p);
440 }
441
442 /**
443 * Causes the handle to cease to track its tracked object (if any).
444 * If the argument passed is not NULL, the handle will track the new
445 * object passed. This method does not throw.
446 * @param ptr NULL (the default), or a new object to track.
447 */
448 void reset(T* ptr = 0) noexcept {
449
450 if (obj_p) g_object_remove_weak_pointer((GObject*)obj_p,
451 (void**)&obj_p);
452 obj_p = ptr;
453 if (ptr) g_object_add_weak_pointer((GObject*)ptr,
454 (void**)&obj_p);
455 }
456
457 /**
458 * The copy constructor does not throw. It constructs a new weak
459 * pointer tracking the same GObject as that tracked by the existing
460 * weak pointer.
461 * @param gobj The handle to be copied.
462 */
463 GobjWeakHandle(const GobjWeakHandle& gobj) noexcept {
464 obj_p = gobj.obj_p;
465 if (obj_p) g_object_add_weak_pointer((GObject*)obj_p,
466 (void**)&obj_p);
467 }
468
469 /**
470 * This constructor constructs a weak pointer for a GObject managed
471 * by a GobjHandle handle. It does not throw.
472 * @param gobj The GobjHandle managing the GObject which the
473 * GobjWeakHandle is to track.
474 */
475 GobjWeakHandle(const GobjHandle<T>& gobj) noexcept {
476 obj_p = gobj.get();
477 if (obj_p) g_object_add_weak_pointer((GObject*)obj_p,
478 (void**)&obj_p);
479 }
480
481 /**
482 * This method does not throw. It causes the handle to cease to
483 * track its tracked object (if any), and begin tracking the same
484 * GObject as that tracked by the assignor. This method does not
485 * throw.
486 * @param gobj The assignor.
487 * @return The GobjWeakHandle object after assignment.
488 */
489 GobjWeakHandle& operator=(const GobjWeakHandle& gobj) noexcept {
490 // self assignment takes care of itself
491 reset(gobj.obj_p);
492 return *this;
493 }
494
495 /**
496 * This method does not throw. It causes the handle to cease to
497 * track its tracked object (if any), and begin tracking the GObject
498 * managed by the GobjHandle argument. This method does not throw.
499 * @param gobj The assignor GobjHandle.
500 * @return The GobjWeakHandle object after assignment.
501 */
502 GobjWeakHandle& operator=(const GobjHandle<T>& gobj) noexcept {
503 reset(gobj.get());
504 return *this;
505 }
506
507 /**
508 * This method does not throw.
509 * @return True if the tracked GObject still exists, or false if it
510 * does not or no GObject is being tracked.
511 * @note The valid() method is a synonym for this method.
512 */
513 operator bool() const noexcept {return obj_p;}
514
515 #ifndef DOXYGEN_PARSING
516 /*
517 * DEPRECATED: Do not use this method as it is only retained for
518 * source compatibility. Its semantics are the wrong way around:
519 * expired() returns true if the GObject still exists, instead of
520 * false. Use operator bool() or the valid() method instead, which
521 * have the correct semantics. This method does not throw.
522 */
523 bool expired() const noexcept {return obj_p;}
524 #endif
525
526 /**
527 * This method does not throw.
528 * @return True if the tracked GObject still exists, or false if it
529 * does not or no GObject is being tracked.
530 * @note operator bool() is a synonym for this method.
531 *
532 * Since 2.0.5
533 */
534 bool valid() const noexcept {return obj_p;}
535
536 /**
537 * This method does not throw.
538 * @return A pointer to the tracked GObject.
539 * @exception GobjWeakHandleError This method will throw
540 * GobjWeakHandleError if the tracked object no longer exists or none
541 * is being tracked. There is no need to check for this exception if
542 * the status of the tracked object has been established with
543 * operator bool() or valid().
544 */
545 T* get() const {if (!obj_p) throw GobjWeakHandleError(); return obj_p;}
546
547 /**
548 * This method does not throw.
549 * @return A reference to the tracked GObject.
550 * @exception GobjWeakHandleError This method will throw
551 * GobjWeakHandleError if the tracked object no longer exists or none
552 * is being tracked. There is no need to check for this exception if
553 * the status of the tracked object has been established with
554 * operator bool() or valid().
555 */
556 T& operator*() const {if (!obj_p) throw GobjWeakHandleError(); return *obj_p;}
557
558 /**
559 * This method does not throw.
560 * @return A pointer to the tracked GObject.
561 * @exception GobjWeakHandleError This method will throw
562 * GobjWeakHandleError if the tracked object no longer exists or none
563 * is being tracked. There is no need to check for this exception if
564 * the status of the tracked object has been established with
565 * operator bool() or valid().
566 */
567 T* operator->() const {if (!obj_p) throw GobjWeakHandleError(); return obj_p;}
568
569 /**
570 * This method does not throw.
571 * @return A pointer to the tracked GObject.
572 * @exception GobjWeakHandleError This method will throw
573 * GobjWeakHandleError if the tracked object no longer exists or none
574 * is being tracked. There is no need to check for this exception if
575 * the status of the tracked object has been established with
576 * operator bool() or valid().
577 */
578 operator T*() const {if (!obj_p) throw GobjWeakHandleError(); return obj_p;}
579
580 /**
581 * The destructor does not throw.
582 */
583 ~GobjWeakHandle() {if (obj_p) g_object_remove_weak_pointer((GObject*)obj_p,
584 (void**)&obj_p);}
585 };
586
587 #if defined(CGU_USE_SMART_PTR_COMPARISON) || defined(DOXYGEN_PARSING)
588
589 // we can use built-in operator == when comparing pointers referencing
590 // different objects of the same type
591 /**
592 * @ingroup handles
593 *
594 * This comparison operator does not throw. It compares the addresses
595 * of the managed objects.
596 *
597 * Since 2.0.0-rc2
598 */
599 template <class T>
600 bool operator==(const GobjHandle<T>& h1, const GobjHandle<T>& h2) noexcept {
601 return (h1.get() == h2.get());
602 }
603
604 /**
605 * @ingroup handles
606 *
607 * This comparison operator does not throw. It compares the addresses
608 * of the managed objects.
609 *
610 * Since 2.0.0-rc2
611 */
612 template <class T>
613 bool operator!=(const GobjHandle<T>& h1, const GobjHandle<T>& h2) noexcept {
614 return !(h1 == h2);
615 }
616
617 // we must use std::less rather than the < built-in operator for
618 // pointers to objects not within the same array or object: "For
619 // templates greater, less, greater_equal, and less_equal, the
620 // specializations for any pointer type yield a total order, even if
621 // the built-in operators <, >, <=, >= do not." (para 20.3.3/8).
622 /**
623 * @ingroup handles
624 *
625 * This comparison operator does not throw unless std::less applied to
626 * pointer types throws (which it would not do with any sane
627 * implementation). It compares the addresses of the managed objects.
628 *
629 * Since 2.0.0-rc2
630 */
631 template <class T>
632 bool operator<(const GobjHandle<T>& h1, const GobjHandle<T>& h2) {
633 return std::less<T*>()(h1.get(), h2.get());
634 }
635
636 #endif // CGU_USE_SMART_PTR_COMPARISON
637
638 } // namespace Cgu
639
640 // doxygen produces long filenames that tar can't handle:
641 // we have generic documentation for std::hash specialisations
642 // in doxygen.main.in
643 #if defined(CGU_USE_SMART_PTR_COMPARISON) && !defined(DOXYGEN_PARSING)
644 /* This struct allows GobjHandle objects to be keys in unordered
645 associative containers */
646 namespace std {
647 template <class T>
648 struct hash<Cgu::GobjHandle<T>> {
649 typedef std::size_t result_type;
650 typedef Cgu::GobjHandle<T> argument_type;
651 result_type operator()(const argument_type& h) const {
652 // this is fine: std::hash structs do not normally contain data and
653 // std::hash<T*> certainly won't, so we don't have overhead constructing
654 // std::hash<T*> on the fly
655 return std::hash<T*>()(h.get());
656 }
657 };
658 } // namespace std
659 #endif // CGU_USE_SMART_PTR_COMPARISON
660
661 #endif
Cgu::GobjWeakHandle::operator*
T & operator*() const
Definition: gobj_handle.h:556
Cgu
Definition: application.h:44
Cgu::GobjHandle::operator*
T & operator*() const noexcept
Definition: gobj_handle.h:298
Cgu::GobjHandle
This is a handle for managing the reference count of GObjects.
Definition: gobj_handle.h:148
Cgu::GobjWeakHandle::get
T * get() const
Definition: gobj_handle.h:545
Cgu::GobjWeakHandle::operator=
GobjWeakHandle & operator=(const GobjHandle< T > &gobj) noexcept
Definition: gobj_handle.h:502
Cgu::GobjWeakHandle::GobjWeakHandle
GobjWeakHandle(const GobjHandle< T > &gobj) noexcept
Definition: gobj_handle.h:475
Cgu::GobjWeakHandleError
Definition: gobj_handle.h:422
Cgu::GobjHandle::reset
void reset(T *ptr=0)
Definition: gobj_handle.h:194
Cgu::GobjHandle::GobjHandle
GobjHandle(T *ptr=0) noexcept
Definition: gobj_handle.h:170
Cgu::GobjWeakHandle::valid
bool valid() const noexcept
Definition: gobj_handle.h:534
Cgu::operator<
bool operator<(const GobjHandle< T > &h1, const GobjHandle< T > &h2)
Definition: gobj_handle.h:632
Cgu::operator!=
bool operator!=(const GobjHandle< T > &h1, const GobjHandle< T > &h2) noexcept
Definition: gobj_handle.h:613
Cgu::GobjHandle::GobjHandle
GobjHandle(GobjHandle &&gobj) noexcept
Definition: gobj_handle.h:220
Cgu::GobjWeakHandle::GobjWeakHandle
GobjWeakHandle(T *ptr=0) noexcept
Definition: gobj_handle.h:436
Cgu::operator==
bool operator==(const GobjHandle< T > &h1, const GobjHandle< T > &h2) noexcept
Definition: gobj_handle.h:600
Cgu::GobjWeakHandle::GobjWeakHandle
GobjWeakHandle(const GobjWeakHandle &gobj) noexcept
Definition: gobj_handle.h:463
Cgu::GobjWeakHandle::~GobjWeakHandle
~GobjWeakHandle()
Definition: gobj_handle.h:583
Cgu::GobjWeakHandle::reset
void reset(T *ptr=0) noexcept
Definition: gobj_handle.h:448
hash
A specialization of std::hash for Cgu::Callback::FunctorArg, Cgu::Callback::SafeFunctorArg,...
Cgu::GobjWeakHandle::operator=
GobjWeakHandle & operator=(const GobjWeakHandle &gobj) noexcept
Definition: gobj_handle.h:489
Cgu::GobjHandle::operator=
GobjHandle & operator=(GobjHandle &&gobj)
Definition: gobj_handle.h:272
Cgu::GobjWeakHandle
This is a handle for managing weak references to GObjects.
Definition: gobj_handle.h:426
Cgu::GobjHandle::GobjHandle
GobjHandle(const GobjHandle &gobj) noexcept
Definition: gobj_handle.h:211
Cgu::GobjHandle::operator->
T * operator->() const noexcept
Definition: gobj_handle.h:305
Cgu::GobjWeakHandle::operator->
T * operator->() const
Definition: gobj_handle.h:567
Cgu::GobjHandle::operator=
GobjHandle & operator=(const GobjHandle &gobj)
Definition: gobj_handle.h:244
cgu_config.h
Cgu::GobjHandle::get
T * get() const noexcept
Definition: gobj_handle.h:292
Cgu::GobjWeakHandleError::what
virtual const char * what() const
Definition: gobj_handle.h:423
Cgu::GobjHandle::~GobjHandle
~GobjHandle()
Definition: gobj_handle.h:319