~unity-api-team/thumbnailer/trusty

« back to all changes in this revision

Viewing changes to include/internal/gobj_memory.h

  • Committer: Package Import Robot
  • Author(s): Ubuntu daily release, Ricardo Salveti de Araujo, Jussi Pakkanen
  • Date: 2014-02-18 23:01:31 UTC
  • mfrom: (1.1.5)
  • Revision ID: package-import@ubuntu.com-20140218230131-tbg5z4nutpa2tusj
Tags: 1.0+14.04.20140218-0ubuntu1
[ Ricardo Salveti de Araujo ]
* vs-thumb: give pipeline at least 3 seconds to preroll

[ Jussi Pakkanen ]
* Created a unique_gobj class for managing gobject based resources.
* Fix use of #includes. (LP: #1237045)
* A bunch of fixes to make the project compile on precise.
* Removed accidentally added file.
* Invalidate cached images when source has changed.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2013 Canonical Ltd.
 
3
 *
 
4
 * This program is free software: you can redistribute it and/or modify
 
5
 * it under the terms of the GNU Lesser General Public License version 3 as
 
6
 * published by the Free Software Foundation.
 
7
 *
 
8
 * This program is distributed in the hope that it will be useful,
 
9
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
11
 * GNU Lesser General Public License for more details.
 
12
 *
 
13
 * You should have received a copy of the GNU Lesser General Public License
 
14
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
15
 *
 
16
 * Authored by: Jussi Pakkanen <jussi.pakkanen@canonical.com>
 
17
 */
 
18
 
 
19
#ifndef GOBJ_MEMORY_H_
 
20
#define GOBJ_MEMORY_H_
 
21
 
 
22
#include<glib-object.h>
 
23
#include<stdexcept>
 
24
 
 
25
/**
 
26
 * This class is meant for automatically managing the lifetime of C objects derived
 
27
 * from gobject. Its API perfectly mirrors the API of unique_ptr except that you
 
28
 * can't define your own deleter function as it is always g_object_unref.
 
29
 *
 
30
 * API/ABI stability is not guaranteed. If you need to pass the object across an ABI
 
31
 * boundary, pass the plain gobject.
 
32
 *
 
33
 * This is how you would use unique_gobj 99% of the time:
 
34
 *
 
35
 * unique_gobj<GSomeType> o(g_some_type_new(...));
 
36
 *
 
37
 * More specifically, the object will decrement the gobject reference count
 
38
 * of the object it points to when it goes out of scope. It will never increment it.
 
39
 * Thus you should only assign to it when already holding a reference. unique_gobj
 
40
 * will then take ownership of that particular reference.
 
41
 *
 
42
 * Floating gobjects can not be put in this container as they are meant to be put
 
43
 * into native gobject aware containers immediately upon construction. Trying to insert
 
44
 * a floating gobject into a unique_gobj will throw an invalid_argument exception. To
 
45
 * prevent accidental memory leaks, the floating gobject is unreffed in this case.
 
46
 */
 
47
template<typename T>
 
48
class unique_gobj final {
 
49
private:
 
50
  T* u;
 
51
 
 
52
  void validate_float(T *t) {
 
53
      if(t != nullptr && g_object_is_floating(G_OBJECT(t))) {
 
54
          throw std::invalid_argument("Tried to add a floating gobject into a unique_gobj.");
 
55
      }
 
56
  }
 
57
 
 
58
public:
 
59
  typedef T element_type;
 
60
  typedef T* pointer;
 
61
  typedef decltype(g_object_unref) deleter_type;
 
62
 
 
63
  constexpr unique_gobj() noexcept : u(nullptr) {}
 
64
  explicit unique_gobj(T *t) : u(t) {
 
65
      // What should we do if validate throws? Unreffing unknown objs
 
66
      // is dodgy but not unreffing runs the risk of
 
67
      // memory leaks. Currently unrefs as u is destroyed
 
68
      // when this exception is thrown.
 
69
      validate_float(t);
 
70
  }
 
71
  constexpr unique_gobj(std::nullptr_t) noexcept : u(nullptr) {};
 
72
  unique_gobj(unique_gobj &&o) noexcept { u = o.u; o.u = nullptr; }
 
73
  unique_gobj(const unique_gobj &o) = delete;
 
74
  unique_gobj& operator=(unique_gobj &o) = delete;
 
75
  ~unique_gobj() { reset(); }
 
76
 
 
77
  deleter_type& get_deleter() noexcept { return g_object_unref; }
 
78
  const deleter_type& get_deleter() const noexcept { return g_object_unref; }
 
79
 
 
80
  void swap(unique_gobj<T> &o) noexcept { T*tmp = u; u = o.u; o.u = tmp; }
 
81
  void reset(pointer p = pointer()) {
 
82
      if(u!=nullptr) {
 
83
          g_object_unref(G_OBJECT(u));
 
84
          u = nullptr;
 
85
      }
 
86
      // Same throw dilemma as in pointer constructor.
 
87
      u = p;
 
88
      validate_float(p);
 
89
  }
 
90
 
 
91
  T* release() noexcept { T* r = u; u=nullptr; return r; }
 
92
  T* get() const noexcept { return u; }
 
93
 
 
94
  T& operator*() const { return *u; }
 
95
  T* operator->() const noexcept { return u; }
 
96
  explicit operator bool() const noexcept { return u != nullptr; }
 
97
 
 
98
  unique_gobj& operator=(unique_gobj &&o) noexcept { reset(); u = o.u; o.u = nullptr; return *this; }
 
99
  unique_gobj& operator=(std::nullptr_t) noexcept { reset(); return *this; }
 
100
  bool operator==(const unique_gobj<T> &o) const noexcept { return u == o.u; }
 
101
  bool operator!=(const unique_gobj<T> &o) const noexcept { return u != o.u; }
 
102
  bool operator<(const unique_gobj<T> &o) const noexcept { return u < o.u; }
 
103
  bool operator<=(const unique_gobj<T> &o) const noexcept { return u <= o.u; }
 
104
  bool operator>(const unique_gobj<T> &o) const noexcept { return u > o.u; }
 
105
  bool operator>=(const unique_gobj<T> &o) const noexcept { return u >= o.u; }
 
106
};
 
107
 
 
108
template<typename T>
 
109
void ::std::swap(unique_gobj<T> &f, unique_gobj<T> &s) noexcept { f.swap(s); }
 
110
 
 
111
 
 
112
#endif