summaryrefslogtreecommitdiff
path: root/tools/m4/class_opaque_copyable.m4
blob: 9e53649ea3a74c8554381264f80212648238fa84 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
dnl $Id$

dnl
dnl _CLASS_OPAQUE_COPYABLE(Region, GdkRegion, gdk_region_new, gdk_region_copy, gdk_region_destroy)
dnl

define(`_CLASS_OPAQUE_COPYABLE',`dnl
_PUSH()
dnl
dnl  Define the args for later macros
define(`__CPPNAME__',`$1')
define(`__CNAME__',`$2')
define(`__OPAQUE_FUNC_NEW',`$3')
define(`__OPAQUE_FUNC_COPY',`$4')
define(`__OPAQUE_FUNC_FREE',`$5')

define(`_CUSTOM_DEFAULT_CTOR',`dnl
_PUSH()
dnl Define this macro to be tested for later.
define(`__BOOL_CUSTOM_DEFAULT_CTOR__',`$1')
_POP()
')

define(`_CUSTOM_CTOR_CAST',`dnl
_PUSH()
dnl Define this macro to be tested for later.
define(`__BOOL_CUSTOM_CTOR_CAST__',`$1')
_POP()
')

_POP()
_SECTION(SECTION_CLASS2)
') dnl End of _CLASS_OPAQUE_COPYABLE.


dnl
dnl _END_CLASS_OPAQUE_COPYABLE()
dnl   denotes the end of a class
dnl
define(`_END_CLASS_OPAQUE_COPYABLE',`

_SECTION(SECTION_HEADER3)

ifdef(`__BOOL_NO_WRAP_FUNCTION__',`dnl
',`dnl else
namespace Glib
{

  /** A Glib::wrap() method for this object.
   * 
   * @param object The C instance.
   * @param take_copy False if the result should take ownership of the C instance. True if it should take a new copy or ref.
   * @result A C++ instance that wraps this C instance.
   *
   * @relates __NAMESPACE__::__CPPNAME__
   */
__NAMESPACE__::__CPPNAME__ wrap(__CNAME__* object, bool take_copy = false);

} // namespace Glib
')dnl endif __BOOL_NO_WRAP_FUNCTION__

_SECTION(SECTION_SRC_GENERATED)

ifdef(`__BOOL_NO_WRAP_FUNCTION__',`dnl
',`dnl else
namespace Glib
{

__NAMESPACE__::__CPPNAME__ wrap(__CNAME__* object, bool take_copy /* = false */)
{
  return __NAMESPACE__::__CPPNAME__`'(object, take_copy);
}

} // namespace Glib
')dnl endif


__NAMESPACE_BEGIN__

dnl
dnl The implementation:
dnl

ifdef(`__BOOL_CUSTOM_DEFAULT_CTOR__',`dnl
',`dnl else
__CPPNAME__::__CPPNAME__`'()
:
ifelse(__OPAQUE_FUNC_NEW,NONE,`dnl
  gobject_ (0) // Allows creation of invalid wrapper, e.g. for output arguments to methods.
',`dnl else
  gobject_ (__OPAQUE_FUNC_NEW`'())
')dnl
{}
')dnl endif __BOOL_CUSTOM_DEFAULT_CTOR__

__CPPNAME__::__CPPNAME__`'(const __CPPNAME__& src)
:
  gobject_ ((src.gobject_) ? __OPAQUE_FUNC_COPY`'(src.gobject_) : 0)
{}

ifdef(`__BOOL_CUSTOM_CTOR_CAST__',,`dnl else
__CPPNAME__::__CPPNAME__`'(__CNAME__* castitem, bool make_a_copy /* = false */)
{
  if(!make_a_copy)
  {
    // It was given to us by a function which has already made a copy for us to keep.
    gobject_ = castitem;
  }
  else
  {
    // We are probably getting it via direct access to a struct,
    // so we can not just take it - we have to take a copy of it.
    if(castitem)
      gobject_ = __OPAQUE_FUNC_COPY`'(castitem);
    else
      gobject_ = 0;
  }
}
')

ifelse(__OPAQUE_FUNC_COPY,NONE,`dnl
',`dnl else
__CPPNAME__& __CPPNAME__::operator=(const __CPPNAME__`'& src)
{
  __CNAME__ *const new_gobject = (src.gobject_) ? __OPAQUE_FUNC_COPY`'(src.gobject_) : 0;

  if(gobject_)
    __OPAQUE_FUNC_FREE`'(gobject_);

  gobject_ = new_gobject;

  return *this;
}
')dnl

__CPPNAME__::~__CPPNAME__`'()
{
  if(gobject_)
    __OPAQUE_FUNC_FREE`'(gobject_);
}

__CNAME__* __CPPNAME__::gobj_copy() const
{
  return __OPAQUE_FUNC_COPY`'(gobject_);
}

_IMPORT(SECTION_CC)

__NAMESPACE_END__


dnl
dnl
dnl
dnl
_POP()
dnl
dnl
dnl The actual class, e.g. Pango::FontDescription, declaration:
dnl
_IMPORT(SECTION_CLASS1)
public:
#ifndef DOXYGEN_SHOULD_SKIP_THIS
  typedef __CPPNAME__ CppObjectType;
  typedef __CNAME__ BaseObjectType;
#endif /* DOXYGEN_SHOULD_SKIP_THIS */

ifdef(`__BOOL_CUSTOM_DEFAULT_CTOR__',`dnl
',`dnl else
  /** Constructs an invalid object.
   * E.g. for output arguments to methods. There is not much you can do with
   * the object before it has been assigned a valid value.
   */
  __CPPNAME__`'();
')dnl

  // Use make_a_copy=true when getting it directly from a struct.
  explicit __CPPNAME__`'(__CNAME__* castitem, bool make_a_copy = false);

  __CPPNAME__`'(const __CPPNAME__& src);
  __CPPNAME__& operator=(const __CPPNAME__& src);

_IMPORT(SECTION_DTOR_DOCUMENTATION)
  ~__CPPNAME__`'();

  __CNAME__*       gobj()       { return gobject_; }
  const __CNAME__* gobj() const { return gobject_; }

  ///Provides access to the underlying C instance. The caller is responsible for freeing it. Use when directly setting fields in structs.
  __CNAME__* gobj_copy() const;

protected:
  __CNAME__* gobject_;

private:
_IMPORT(SECTION_CLASS2)
')