mirror of https://github.com/KLayout/klayout.git
Avoid an issue with virtual functions
Reimplementing virtual functions with
"const &" arguments wasn't behaving as
expected because these arguments were
copied.
Now, "const &" for arguments (in virtual
function reimplementation) is not implemented
as a copy.
In addition, now it's possible to declare
results as references always (also if const &).
See gsiTest.cc:1078 for example:
// gsi::arg_make_reference makes the function's return value
// always being taken as a reference
gsi::method<C_P, const CopyDetector &, const CopyDetector &, gsi::arg_make_reference> ("pass_cd_cref_as_ref", &C_P::pass_cd_cref)
This commit is contained in:
parent
4068478887
commit
30e26c4f96
|
|
@ -334,11 +334,23 @@ public:
|
|||
/**
|
||||
* @brief Adds an argument to the argument list (of type X)
|
||||
*/
|
||||
template <class X>
|
||||
template <class X>
|
||||
void add_arg ()
|
||||
{
|
||||
ArgType a;
|
||||
a.template init<X> ();
|
||||
a.template init<X, arg_make_reference> ();
|
||||
m_arg_types.push_back (a);
|
||||
m_argsize += a.size ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Adds an argument to the argument list (of type X)
|
||||
*/
|
||||
template <class X, class Transfer>
|
||||
void add_arg ()
|
||||
{
|
||||
ArgType a;
|
||||
a.template init<X, Transfer> ();
|
||||
m_arg_types.push_back (a);
|
||||
m_argsize += a.size ();
|
||||
}
|
||||
|
|
@ -346,11 +358,23 @@ public:
|
|||
/**
|
||||
* @brief Adds an argument to the argument list (of type X plus additional specs)
|
||||
*/
|
||||
template <class X>
|
||||
template <class X>
|
||||
void add_arg (const ArgSpecBase &spec)
|
||||
{
|
||||
ArgType a;
|
||||
a.template init<X> (spec);
|
||||
a.template init<X, arg_make_reference> (spec);
|
||||
m_arg_types.push_back (a);
|
||||
m_argsize += a.size ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Adds an argument to the argument list (of type X plus additional specs)
|
||||
*/
|
||||
template <class X, class Transfer>
|
||||
void add_arg (const ArgSpecBase &spec)
|
||||
{
|
||||
ArgType a;
|
||||
a.template init<X, Transfer> (spec);
|
||||
m_arg_types.push_back (a);
|
||||
m_argsize += a.size ();
|
||||
}
|
||||
|
|
@ -358,11 +382,23 @@ public:
|
|||
/**
|
||||
* @brief This version will take the ownership of the ArgSpecBase object
|
||||
*/
|
||||
template <class X>
|
||||
template <class X>
|
||||
void add_arg (ArgSpecBase *spec)
|
||||
{
|
||||
ArgType a;
|
||||
a.template init<X> (spec);
|
||||
a.template init<X, arg_make_reference> (spec);
|
||||
m_arg_types.push_back (a);
|
||||
m_argsize += a.size ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This version will take the ownership of the ArgSpecBase object
|
||||
*/
|
||||
template <class X, class Transfer>
|
||||
void add_arg (ArgSpecBase *spec)
|
||||
{
|
||||
ArgType a;
|
||||
a.template init<X, Transfer> (spec);
|
||||
m_arg_types.push_back (a);
|
||||
m_argsize += a.size ();
|
||||
}
|
||||
|
|
@ -379,10 +415,19 @@ public:
|
|||
/**
|
||||
* @brief Sets the return type to "X"
|
||||
*/
|
||||
template <class X>
|
||||
template <class X>
|
||||
void set_return ()
|
||||
{
|
||||
m_ret_type.template init<X> ();
|
||||
m_ret_type.template init<X, arg_default_return_value_preference> ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the return type to "X"
|
||||
*/
|
||||
template <class X, class Transfer>
|
||||
void set_return ()
|
||||
{
|
||||
m_ret_type.template init<X, Transfer> ();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -391,7 +436,7 @@ public:
|
|||
template <class X>
|
||||
void set_return_new ()
|
||||
{
|
||||
m_ret_type.template init<X> (true);
|
||||
m_ret_type.template init<X, arg_pass_ownership> ();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -853,16 +898,6 @@ constant (const std::string &name, const R &v, const std::string &doc = std::str
|
|||
return Methods (new ConstantValueGetter <R> (name, v, doc));
|
||||
}
|
||||
|
||||
struct return_by_value
|
||||
{
|
||||
typedef tl::False is_factory;
|
||||
};
|
||||
|
||||
struct return_new_object
|
||||
{
|
||||
typedef tl::True is_factory;
|
||||
};
|
||||
|
||||
// 0 argument
|
||||
|
||||
#define _COUNT 0
|
||||
|
|
|
|||
|
|
@ -220,7 +220,7 @@ private:
|
|||
_ARGSPECMEM
|
||||
};
|
||||
|
||||
template <class X, class R _COMMA _TMPLARG, class F = gsi::return_by_value>
|
||||
template <class X, class R _COMMA _TMPLARG, class Transfer = gsi::arg_default_return_value_preference>
|
||||
class _NAME(Method)
|
||||
: public MethodSpecificBase <X>
|
||||
{
|
||||
|
|
@ -240,11 +240,7 @@ public:
|
|||
{
|
||||
this->clear ();
|
||||
_ADDARGS
|
||||
if (tl::value_from_type (typename F::is_factory ())) {
|
||||
this->template set_return_new<R> ();
|
||||
} else {
|
||||
this->template set_return<R> ();
|
||||
}
|
||||
this->template set_return<R, Transfer> ();
|
||||
}
|
||||
|
||||
virtual MethodBase *clone () const
|
||||
|
|
@ -268,7 +264,7 @@ private:
|
|||
_ARGSPECMEM
|
||||
};
|
||||
|
||||
template <class X, class R _COMMA _TMPLARG, class F = gsi::return_by_value>
|
||||
template <class X, class R _COMMA _TMPLARG, class Transfer = gsi::arg_default_return_value_preference>
|
||||
class _NAME(ConstMethod)
|
||||
: public MethodSpecificBase <X>
|
||||
{
|
||||
|
|
@ -288,11 +284,7 @@ public:
|
|||
{
|
||||
this->clear ();
|
||||
_ADDARGS
|
||||
if (tl::value_from_type (typename F::is_factory ())) {
|
||||
this->template set_return_new<R> ();
|
||||
} else {
|
||||
this->template set_return<R> ();
|
||||
}
|
||||
this->template set_return<R, Transfer> ();
|
||||
}
|
||||
|
||||
virtual MethodBase *clone () const
|
||||
|
|
@ -316,7 +308,7 @@ private:
|
|||
_ARGSPECMEM
|
||||
};
|
||||
|
||||
template <class X, class R _COMMA _TMPLARG, class F = gsi::return_by_value>
|
||||
template <class X, class R _COMMA _TMPLARG, class Transfer = gsi::arg_default_return_value_preference>
|
||||
class _NAME(ExtMethod)
|
||||
: public MethodBase
|
||||
{
|
||||
|
|
@ -336,11 +328,7 @@ public:
|
|||
{
|
||||
this->clear ();
|
||||
_ADDARGS
|
||||
if (tl::value_from_type (typename F::is_factory ())) {
|
||||
this->template set_return_new<R> ();
|
||||
} else {
|
||||
this->template set_return<R> ();
|
||||
}
|
||||
this->template set_return<R, Transfer> ();
|
||||
}
|
||||
|
||||
virtual MethodBase *clone () const
|
||||
|
|
@ -364,7 +352,7 @@ private:
|
|||
_ARGSPECMEM
|
||||
};
|
||||
|
||||
template <class R _COMMA _TMPLARG, class F = gsi::return_by_value>
|
||||
template <class R _COMMA _TMPLARG, class Transfer = gsi::arg_default_return_value_preference>
|
||||
class _NAME(StaticMethod)
|
||||
: public StaticMethodBase
|
||||
{
|
||||
|
|
@ -384,11 +372,7 @@ public:
|
|||
{
|
||||
this->clear ();
|
||||
_ADDARGS
|
||||
if (tl::value_from_type (typename F::is_factory ())) {
|
||||
this->template set_return_new<R> ();
|
||||
} else {
|
||||
this->template set_return<R> ();
|
||||
}
|
||||
this->template set_return<R, Transfer> ();
|
||||
}
|
||||
|
||||
virtual MethodBase *clone () const
|
||||
|
|
@ -1300,7 +1284,14 @@ template <class X, class R _COMMA _TMPLARG>
|
|||
Methods
|
||||
method (const std::string &name, R (X::*m) (_FUNCARGLIST), const std::string &doc = std::string ())
|
||||
{
|
||||
return Methods (new _NAME(Method) <X, R _COMMA _FUNCARGLIST> (name, m, doc));
|
||||
return Methods (new _NAME(Method) <X, R _COMMA _FUNCARGLIST, arg_default_return_value_preference> (name, m, doc));
|
||||
}
|
||||
|
||||
template <class X, class R _COMMA _TMPLARG, class Transfer>
|
||||
Methods
|
||||
method (const std::string &name, R (X::*m) (_FUNCARGLIST), const std::string &doc = std::string ())
|
||||
{
|
||||
return Methods (new _NAME(Method) <X, R _COMMA _FUNCARGLIST, Transfer> (name, m, doc));
|
||||
}
|
||||
|
||||
#if _COUNT != 0
|
||||
|
|
@ -1308,7 +1299,14 @@ template <class X, class R _COMMA _TMPLARG _COMMA _TMPLARGSPECS>
|
|||
Methods
|
||||
method (const std::string &name, R (X::*m) (_FUNCARGLIST) _COMMA _ARGSPECS, const std::string &doc = std::string ())
|
||||
{
|
||||
return Methods ((new _NAME(Method) <X, R _COMMA _FUNCARGLIST> (name, m, doc))->add_args (_ARGSPECARGS));
|
||||
return Methods ((new _NAME(Method) <X, R _COMMA _FUNCARGLIST, arg_default_return_value_preference> (name, m, doc))->add_args (_ARGSPECARGS));
|
||||
}
|
||||
|
||||
template <class X, class R _COMMA _TMPLARG _COMMA _TMPLARGSPECS, class Transfer>
|
||||
Methods
|
||||
method (const std::string &name, R (X::*m) (_FUNCARGLIST) _COMMA _ARGSPECS, const std::string &doc = std::string ())
|
||||
{
|
||||
return Methods ((new _NAME(Method) <X, R _COMMA _FUNCARGLIST, Transfer> (name, m, doc))->add_args (_ARGSPECARGS));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -1316,7 +1314,7 @@ template <class X, class R _COMMA _TMPLARG>
|
|||
Methods
|
||||
factory (const std::string &name, R *(X::*m) (_FUNCARGLIST), const std::string &doc = std::string ())
|
||||
{
|
||||
return Methods (new _NAME(Method) <X, R * _COMMA _FUNCARGLIST, gsi::return_new_object> (name, m, doc));
|
||||
return Methods (new _NAME(Method) <X, R * _COMMA _FUNCARGLIST, gsi::arg_pass_ownership> (name, m, doc));
|
||||
}
|
||||
|
||||
#if _COUNT != 0
|
||||
|
|
@ -1324,7 +1322,7 @@ template <class X, class R _COMMA _TMPLARG _COMMA _TMPLARGSPECS>
|
|||
Methods
|
||||
factory (const std::string &name, R *(X::*m) (_FUNCARGLIST) _COMMA _ARGSPECS, const std::string &doc = std::string ())
|
||||
{
|
||||
return Methods ((new _NAME(Method) <X, R * _COMMA _FUNCARGLIST, gsi::return_new_object> (name, m, doc))->add_args (_ARGSPECARGS));
|
||||
return Methods ((new _NAME(Method) <X, R * _COMMA _FUNCARGLIST, gsi::arg_pass_ownership> (name, m, doc))->add_args (_ARGSPECARGS));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -1332,7 +1330,14 @@ template <class X, class R _COMMA _TMPLARG>
|
|||
Methods
|
||||
method_ext (const std::string &name, R (*xm) (X * _COMMA _FUNCARGLIST), const std::string &doc = std::string ())
|
||||
{
|
||||
return Methods (new _NAME(ExtMethod) <X, R _COMMA _FUNCARGLIST> (name, xm, doc));
|
||||
return Methods (new _NAME(ExtMethod) <X, R _COMMA _FUNCARGLIST, arg_default_return_value_preference> (name, xm, doc));
|
||||
}
|
||||
|
||||
template <class X, class R _COMMA _TMPLARG, class Transfer>
|
||||
Methods
|
||||
method_ext (const std::string &name, R (*xm) (X * _COMMA _FUNCARGLIST), const std::string &doc = std::string ())
|
||||
{
|
||||
return Methods (new _NAME(ExtMethod) <X, R _COMMA _FUNCARGLIST, Transfer> (name, xm, doc));
|
||||
}
|
||||
|
||||
#if _COUNT != 0
|
||||
|
|
@ -1340,7 +1345,14 @@ template <class X, class R _COMMA _TMPLARG _COMMA _TMPLARGSPECS>
|
|||
Methods
|
||||
method_ext (const std::string &name, R (*xm) (X * _COMMA _FUNCARGLIST) _COMMA _ARGSPECS, const std::string &doc = std::string ())
|
||||
{
|
||||
return Methods ((new _NAME(ExtMethod) <X, R _COMMA _FUNCARGLIST> (name, xm, doc))->add_args (_ARGSPECARGS));
|
||||
return Methods ((new _NAME(ExtMethod) <X, R _COMMA _FUNCARGLIST, arg_default_return_value_preference> (name, xm, doc))->add_args (_ARGSPECARGS));
|
||||
}
|
||||
|
||||
template <class X, class R _COMMA _TMPLARG _COMMA _TMPLARGSPECS, class Transfer>
|
||||
Methods
|
||||
method_ext (const std::string &name, R (*xm) (X * _COMMA _FUNCARGLIST) _COMMA _ARGSPECS, const std::string &doc = std::string ())
|
||||
{
|
||||
return Methods ((new _NAME(ExtMethod) <X, R _COMMA _FUNCARGLIST, Transfer> (name, xm, doc))->add_args (_ARGSPECARGS));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -1348,7 +1360,7 @@ template <class X, class R _COMMA _TMPLARG>
|
|||
Methods
|
||||
factory_ext (const std::string &name, R *(*xm) (X * _COMMA _FUNCARGLIST), const std::string &doc = std::string ())
|
||||
{
|
||||
return Methods (new _NAME(ExtMethod) <X, R * _COMMA _FUNCARGLIST, gsi::return_new_object> (name, xm, doc));
|
||||
return Methods (new _NAME(ExtMethod) <X, R * _COMMA _FUNCARGLIST, gsi::arg_pass_ownership> (name, xm, doc));
|
||||
}
|
||||
|
||||
#if _COUNT != 0
|
||||
|
|
@ -1356,7 +1368,7 @@ template <class X, class R _COMMA _TMPLARG _COMMA _TMPLARGSPECS>
|
|||
Methods
|
||||
factory_ext (const std::string &name, R *(*xm) (X * _COMMA _FUNCARGLIST) _COMMA _ARGSPECS, const std::string &doc = std::string ())
|
||||
{
|
||||
return Methods ((new _NAME(ExtMethod) <X, R * _COMMA _FUNCARGLIST, gsi::return_new_object> (name, xm, doc))->add_args (_ARGSPECARGS));
|
||||
return Methods ((new _NAME(ExtMethod) <X, R * _COMMA _FUNCARGLIST, gsi::arg_pass_ownership> (name, xm, doc))->add_args (_ARGSPECARGS));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -1364,7 +1376,7 @@ template <class X _COMMA _TMPLARG>
|
|||
Methods
|
||||
constructor (const std::string &name, X *(*m) (_FUNCARGLIST), const std::string &doc = std::string ())
|
||||
{
|
||||
return Methods (new _NAME(StaticMethod) <X * _COMMA _FUNCARGLIST, gsi::return_new_object> (name, m, doc));
|
||||
return Methods (new _NAME(StaticMethod) <X * _COMMA _FUNCARGLIST, gsi::arg_pass_ownership> (name, m, doc));
|
||||
}
|
||||
|
||||
#if _COUNT != 0
|
||||
|
|
@ -1372,7 +1384,7 @@ template <class X _COMMA _TMPLARG _COMMA _TMPLARGSPECS>
|
|||
Methods
|
||||
constructor (const std::string &name, X *(*m) (_FUNCARGLIST) _COMMA _ARGSPECS, const std::string &doc = std::string ())
|
||||
{
|
||||
return Methods ((new _NAME(StaticMethod) <X * _COMMA _FUNCARGLIST, gsi::return_new_object> (name, m, doc))->add_args (_ARGSPECARGS));
|
||||
return Methods ((new _NAME(StaticMethod) <X * _COMMA _FUNCARGLIST, gsi::arg_pass_ownership> (name, m, doc))->add_args (_ARGSPECARGS));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -1380,7 +1392,14 @@ template <class R _COMMA _TMPLARG>
|
|||
Methods
|
||||
method (const std::string &name, R (*m) (_FUNCARGLIST), const std::string &doc = std::string ())
|
||||
{
|
||||
return Methods (new _NAME(StaticMethod) <R _COMMA _FUNCARGLIST> (name, m, doc));
|
||||
return Methods (new _NAME(StaticMethod) <R _COMMA _FUNCARGLIST, arg_default_return_value_preference> (name, m, doc));
|
||||
}
|
||||
|
||||
template <class R _COMMA _TMPLARG, class Transfer>
|
||||
Methods
|
||||
method (const std::string &name, R (*m) (_FUNCARGLIST), const std::string &doc = std::string ())
|
||||
{
|
||||
return Methods (new _NAME(StaticMethod) <R _COMMA _FUNCARGLIST, Transfer> (name, m, doc));
|
||||
}
|
||||
|
||||
#if _COUNT != 0
|
||||
|
|
@ -1388,7 +1407,14 @@ template <class R _COMMA _TMPLARG _COMMA _TMPLARGSPECS>
|
|||
Methods
|
||||
method (const std::string &name, R (*m) (_FUNCARGLIST) _COMMA _ARGSPECS, const std::string &doc = std::string ())
|
||||
{
|
||||
return Methods ((new _NAME(StaticMethod) <R _COMMA _FUNCARGLIST> (name, m, doc))->add_args (_ARGSPECARGS));
|
||||
return Methods ((new _NAME(StaticMethod) <R _COMMA _FUNCARGLIST, arg_default_return_value_preference> (name, m, doc))->add_args (_ARGSPECARGS));
|
||||
}
|
||||
|
||||
template <class R _COMMA _TMPLARG _COMMA _TMPLARGSPECS, class Transfer>
|
||||
Methods
|
||||
method (const std::string &name, R (*m) (_FUNCARGLIST) _COMMA _ARGSPECS, const std::string &doc = std::string ())
|
||||
{
|
||||
return Methods ((new _NAME(StaticMethod) <R _COMMA _FUNCARGLIST, Transfer> (name, m, doc))->add_args (_ARGSPECARGS));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -1396,7 +1422,7 @@ template <class R _COMMA _TMPLARG>
|
|||
Methods
|
||||
factory (const std::string &name, R *(*m) (_FUNCARGLIST), const std::string &doc = std::string ())
|
||||
{
|
||||
return Methods (new _NAME(StaticMethod) <R * _COMMA _FUNCARGLIST, gsi::return_new_object> (name, m, doc));
|
||||
return Methods (new _NAME(StaticMethod) <R * _COMMA _FUNCARGLIST, gsi::arg_pass_ownership> (name, m, doc));
|
||||
}
|
||||
|
||||
#if _COUNT != 0
|
||||
|
|
@ -1404,7 +1430,7 @@ template <class R _COMMA _TMPLARG _COMMA _TMPLARGSPECS>
|
|||
Methods
|
||||
factory (const std::string &name, R *(*m) (_FUNCARGLIST) _COMMA _ARGSPECS, const std::string &doc = std::string ())
|
||||
{
|
||||
return Methods ((new _NAME(StaticMethod) <R * _COMMA _FUNCARGLIST, gsi::return_new_object> (name, m, doc))->add_args (_ARGSPECARGS));
|
||||
return Methods ((new _NAME(StaticMethod) <R * _COMMA _FUNCARGLIST, gsi::arg_pass_ownership> (name, m, doc))->add_args (_ARGSPECARGS));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -1428,7 +1454,7 @@ template <class X, class R _COMMA _TMPLARG>
|
|||
Methods
|
||||
factory_callback (const std::string &name, R (X::*m) (_FUNCARGLIST), Callback X::*cb, const std::string &doc = std::string ())
|
||||
{
|
||||
return Methods (new _NAME(Method) <X, R _COMMA _FUNCARGLIST, gsi::return_new_object> (name, m, doc, cb));
|
||||
return Methods (new _NAME(Method) <X, R _COMMA _FUNCARGLIST, gsi::arg_pass_ownership> (name, m, doc, cb));
|
||||
}
|
||||
|
||||
#if _COUNT != 0
|
||||
|
|
@ -1436,7 +1462,7 @@ template <class X, class R _COMMA _TMPLARG _COMMA _TMPLARGSPECS>
|
|||
Methods
|
||||
factory_callback (const std::string &name, R (X::*m) (_FUNCARGLIST), Callback X::*cb _COMMA _ARGSPECS, const std::string &doc = std::string ())
|
||||
{
|
||||
return Methods ((new _NAME(Method) <X, R _COMMA _FUNCARGLIST, gsi::return_new_object> (name, m, doc, cb))->add_args (_ARGSPECARGS));
|
||||
return Methods ((new _NAME(Method) <X, R _COMMA _FUNCARGLIST, gsi::arg_pass_ownership> (name, m, doc, cb))->add_args (_ARGSPECARGS));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -1444,7 +1470,14 @@ template <class X, class R _COMMA _TMPLARG>
|
|||
Methods
|
||||
method (const std::string &name, R (X::*m) (_FUNCARGLIST) const, const std::string &doc = std::string ())
|
||||
{
|
||||
return Methods (new _NAME(ConstMethod) <X, R _COMMA _FUNCARGLIST> (name, m, doc));
|
||||
return Methods (new _NAME(ConstMethod) <X, R _COMMA _FUNCARGLIST, arg_default_return_value_preference> (name, m, doc));
|
||||
}
|
||||
|
||||
template <class X, class R _COMMA _TMPLARG, class Transfer>
|
||||
Methods
|
||||
method (const std::string &name, R (X::*m) (_FUNCARGLIST) const, const std::string &doc = std::string ())
|
||||
{
|
||||
return Methods (new _NAME(ConstMethod) <X, R _COMMA _FUNCARGLIST, Transfer> (name, m, doc));
|
||||
}
|
||||
|
||||
#if _COUNT != 0
|
||||
|
|
@ -1452,7 +1485,14 @@ template <class X, class R _COMMA _TMPLARG _COMMA _TMPLARGSPECS>
|
|||
Methods
|
||||
method (const std::string &name, R (X::*m) (_FUNCARGLIST) const _COMMA _ARGSPECS, const std::string &doc = std::string ())
|
||||
{
|
||||
return Methods ((new _NAME(ConstMethod) <X, R _COMMA _FUNCARGLIST> (name, m, doc))->add_args (_ARGSPECARGS));
|
||||
return Methods ((new _NAME(ConstMethod) <X, R _COMMA _FUNCARGLIST, arg_default_return_value_preference> (name, m, doc))->add_args (_ARGSPECARGS));
|
||||
}
|
||||
|
||||
template <class X, class R _COMMA _TMPLARG _COMMA _TMPLARGSPECS, class Transfer>
|
||||
Methods
|
||||
method (const std::string &name, R (X::*m) (_FUNCARGLIST) const _COMMA _ARGSPECS, const std::string &doc = std::string ())
|
||||
{
|
||||
return Methods ((new _NAME(ConstMethod) <X, R _COMMA _FUNCARGLIST, Transfer> (name, m, doc))->add_args (_ARGSPECARGS));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -1460,7 +1500,7 @@ template <class X, class R _COMMA _TMPLARG>
|
|||
Methods
|
||||
factory (const std::string &name, R *(X::*m) (_FUNCARGLIST) const, const std::string &doc = std::string ())
|
||||
{
|
||||
return Methods (new _NAME(ConstMethod) <X, R * _COMMA _FUNCARGLIST, gsi::return_new_object> (name, m, doc));
|
||||
return Methods (new _NAME(ConstMethod) <X, R * _COMMA _FUNCARGLIST, gsi::arg_pass_ownership> (name, m, doc));
|
||||
}
|
||||
|
||||
#if _COUNT != 0
|
||||
|
|
@ -1468,7 +1508,7 @@ template <class X, class R _COMMA _TMPLARG _COMMA _TMPLARGSPECS>
|
|||
Methods
|
||||
factory (const std::string &name, R *(X::*m) (_FUNCARGLIST) const _COMMA _ARGSPECS, const std::string &doc = std::string ())
|
||||
{
|
||||
return Methods ((new _NAME(ConstMethod) <X, R * _COMMA _FUNCARGLIST, gsi::return_new_object> (name, m, doc))->add_args (_ARGSPECARGS));
|
||||
return Methods ((new _NAME(ConstMethod) <X, R * _COMMA _FUNCARGLIST, gsi::arg_pass_ownership> (name, m, doc))->add_args (_ARGSPECARGS));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -1492,7 +1532,7 @@ template <class X, class R _COMMA _TMPLARG>
|
|||
Methods
|
||||
factory_callback (const std::string &name, R (X::*m) (_FUNCARGLIST) const, Callback X::*cb, const std::string &doc = std::string ())
|
||||
{
|
||||
return Methods (new _NAME(ConstMethod) <X, R _COMMA _FUNCARGLIST, gsi::return_new_object> (name, m, doc, cb));
|
||||
return Methods (new _NAME(ConstMethod) <X, R _COMMA _FUNCARGLIST, gsi::arg_pass_ownership> (name, m, doc, cb));
|
||||
}
|
||||
|
||||
#if _COUNT != 0
|
||||
|
|
@ -1500,7 +1540,7 @@ template <class X, class R _COMMA _TMPLARG _COMMA _TMPLARGSPECS>
|
|||
Methods
|
||||
factory_callback (const std::string &name, R (X::*m) (_FUNCARGLIST) const, Callback X::*cb _COMMA _ARGSPECS, const std::string &doc = std::string ())
|
||||
{
|
||||
return Methods ((new _NAME(ConstMethod) <X, R _COMMA _FUNCARGLIST, gsi::return_new_object> (name, m, doc, cb))->add_args (_ARGSPECARGS));
|
||||
return Methods ((new _NAME(ConstMethod) <X, R _COMMA _FUNCARGLIST, gsi::arg_pass_ownership> (name, m, doc, cb))->add_args (_ARGSPECARGS));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ ArgType::to_string () const
|
|||
ArgType::ArgType ()
|
||||
: m_type (T_void), mp_spec (0), mp_inner (0), mp_inner_k (0),
|
||||
m_is_ref (false), m_is_ptr (false), m_is_cref (false), m_is_cptr (false), m_is_iter (false),
|
||||
m_owns_spec (false), m_pass_obj (false),
|
||||
m_owns_spec (false), m_pass_obj (false), m_prefer_copy (false),
|
||||
mp_cls (0), m_size (0)
|
||||
{ }
|
||||
|
||||
|
|
@ -132,7 +132,7 @@ ArgType::~ArgType ()
|
|||
ArgType::ArgType (const ArgType &other)
|
||||
: m_type (T_void), mp_spec (0), mp_inner (0), mp_inner_k (0),
|
||||
m_is_ref (false), m_is_ptr (false), m_is_cref (false), m_is_cptr (false), m_is_iter (false),
|
||||
m_owns_spec (false), m_pass_obj (false),
|
||||
m_owns_spec (false), m_pass_obj (false), m_prefer_copy (false),
|
||||
mp_cls (0), m_size (0)
|
||||
{
|
||||
operator= (other);
|
||||
|
|
@ -156,6 +156,7 @@ ArgType::operator= (const ArgType &other)
|
|||
|
||||
m_type = other.m_type;
|
||||
m_pass_obj = other.m_pass_obj;
|
||||
m_prefer_copy = other.m_prefer_copy;
|
||||
m_is_ref = other.m_is_ref;
|
||||
m_is_cref = other.m_is_cref;
|
||||
m_is_ptr = other.m_is_ptr;
|
||||
|
|
@ -204,7 +205,7 @@ ArgType::operator== (const ArgType &b) const
|
|||
}
|
||||
return m_type == b.m_type && m_is_iter == b.m_is_iter &&
|
||||
m_is_ref == b.m_is_ref && m_is_cref == b.m_is_cref && m_is_ptr == b.m_is_ptr && m_is_cptr == b.m_is_cptr &&
|
||||
mp_cls == b.mp_cls && m_pass_obj == b.m_pass_obj;
|
||||
mp_cls == b.mp_cls && m_pass_obj == b.m_pass_obj && m_prefer_copy == b.m_prefer_copy;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -1385,6 +1385,67 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A tag indicating ownership transfer
|
||||
* This tag will transfer ownership of an object (either back- or forward).
|
||||
*/
|
||||
struct arg_pass_ownership { };
|
||||
|
||||
/**
|
||||
* @brief A tag indicating copy preference
|
||||
* By specifying this tag, making a copy of the object is the preferred transfer method
|
||||
*/
|
||||
struct arg_make_copy { };
|
||||
|
||||
/**
|
||||
* @brief A tag indicating to take the reference of an object
|
||||
* By specifying this tag, taking a reference is the preferred transfer method
|
||||
*/
|
||||
struct arg_make_reference { };
|
||||
|
||||
/**
|
||||
* @brief A tag indicating the default return value preference
|
||||
* The default return value preference is "copy" for const references and direct values
|
||||
* and reference otherwise.
|
||||
*/
|
||||
struct arg_default_return_value_preference { };
|
||||
|
||||
/**
|
||||
* @brief A function computing the "prefer_copy" value
|
||||
*/
|
||||
template <class Transfer, class X>
|
||||
struct compute_prefer_copy
|
||||
{
|
||||
static bool value () { return false; }
|
||||
};
|
||||
|
||||
template <class X>
|
||||
struct compute_prefer_copy<arg_default_return_value_preference, X>
|
||||
{
|
||||
static bool value () { return type_traits<X>::is_cref (); }
|
||||
};
|
||||
|
||||
template <class X>
|
||||
struct compute_prefer_copy<arg_make_copy, X>
|
||||
{
|
||||
static bool value () { return true; }
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A function computing the "pass_obj" value
|
||||
*/
|
||||
template <class Transfer, class X>
|
||||
struct compute_pass_obj
|
||||
{
|
||||
static bool value () { return false; }
|
||||
};
|
||||
|
||||
template <class X>
|
||||
struct compute_pass_obj<arg_pass_ownership, X>
|
||||
{
|
||||
static bool value () { return true; }
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Generic argument type declaration
|
||||
*
|
||||
|
|
@ -1427,7 +1488,22 @@ public:
|
|||
template <class X>
|
||||
void init (const ArgSpecBase &spec)
|
||||
{
|
||||
init<X> ();
|
||||
init<X, arg_default_return_value_preference> ();
|
||||
mp_spec = &spec;
|
||||
m_owns_spec = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initializes with an external specification
|
||||
*
|
||||
* This method will initialize the type object referring to an external
|
||||
* spec object. The spec object will specify name and default
|
||||
* value for arguments
|
||||
*/
|
||||
template <class X, class Transfer>
|
||||
void init (const ArgSpecBase &spec)
|
||||
{
|
||||
init<X, Transfer> ();
|
||||
mp_spec = &spec;
|
||||
m_owns_spec = false;
|
||||
}
|
||||
|
|
@ -1442,7 +1518,22 @@ public:
|
|||
template <class X>
|
||||
void init (ArgSpecBase *spec)
|
||||
{
|
||||
init<X> ();
|
||||
init<X, arg_default_return_value_preference> ();
|
||||
mp_spec = spec;
|
||||
m_owns_spec = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initializes with a specification
|
||||
*
|
||||
* This method will initialize the type object with a specification.
|
||||
* The ownership over the specification object will be transferred to
|
||||
* the type object.
|
||||
*/
|
||||
template <class X, class Transfer>
|
||||
void init (ArgSpecBase *spec)
|
||||
{
|
||||
init<X, Transfer> ();
|
||||
mp_spec = spec;
|
||||
m_owns_spec = true;
|
||||
}
|
||||
|
|
@ -1454,7 +1545,7 @@ public:
|
|||
* to the case of object pointers mainly.
|
||||
*/
|
||||
template <class X>
|
||||
void init (bool pass_obj = false)
|
||||
void init ()
|
||||
{
|
||||
release_spec ();
|
||||
|
||||
|
|
@ -1462,7 +1553,8 @@ public:
|
|||
m_is_iter = type_traits<X>::is_iter ();
|
||||
mp_cls = type_traits<X>::cls_decl ();
|
||||
|
||||
m_pass_obj = pass_obj;
|
||||
m_pass_obj = compute_pass_obj<arg_default_return_value_preference, X>::value ();
|
||||
m_prefer_copy = compute_prefer_copy<arg_default_return_value_preference, X>::value ();
|
||||
m_is_ref = type_traits<X>::is_ref ();
|
||||
m_is_ptr = type_traits<X>::is_ptr ();
|
||||
m_is_cref = type_traits<X>::is_cref ();
|
||||
|
|
@ -1481,12 +1573,56 @@ public:
|
|||
|
||||
if (type_traits<typename type_traits<X>::inner_type>::code () != T_void) {
|
||||
mp_inner = new ArgType;
|
||||
mp_inner->init<typename type_traits<X>::inner_type> ();
|
||||
mp_inner->init<typename type_traits<X>::inner_type, arg_make_reference> ();
|
||||
}
|
||||
|
||||
if (type_traits<typename type_traits<X>::inner_k_type>::code () != T_void) {
|
||||
mp_inner_k = new ArgType;
|
||||
mp_inner_k->init<typename type_traits<X>::inner_k_type> ();
|
||||
mp_inner_k->init<typename type_traits<X>::inner_k_type, arg_make_reference> ();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialize the type from a given type X
|
||||
* If "pass_obj" is true, the receiver of an object will always
|
||||
* take over the ownership over the passed object. This applies
|
||||
* to the case of object pointers mainly.
|
||||
*/
|
||||
template <class X, class Transfer>
|
||||
void init ()
|
||||
{
|
||||
release_spec ();
|
||||
|
||||
m_type = type_traits<X>::code ();
|
||||
m_is_iter = type_traits<X>::is_iter ();
|
||||
mp_cls = type_traits<X>::cls_decl ();
|
||||
|
||||
m_pass_obj = compute_pass_obj<Transfer, X>::value ();
|
||||
m_prefer_copy = compute_prefer_copy<Transfer, X>::value ();
|
||||
m_is_ref = type_traits<X>::is_ref ();
|
||||
m_is_ptr = type_traits<X>::is_ptr ();
|
||||
m_is_cref = type_traits<X>::is_cref ();
|
||||
m_is_cptr = type_traits<X>::is_cptr ();
|
||||
m_size = (unsigned int) type_traits<X>::serial_size ();
|
||||
|
||||
if (mp_inner) {
|
||||
delete mp_inner;
|
||||
mp_inner = 0;
|
||||
}
|
||||
|
||||
if (mp_inner_k) {
|
||||
delete mp_inner_k;
|
||||
mp_inner_k = 0;
|
||||
}
|
||||
|
||||
if (type_traits<typename type_traits<X>::inner_type>::code () != T_void) {
|
||||
mp_inner = new ArgType;
|
||||
mp_inner->init<typename type_traits<X>::inner_type, arg_make_reference> ();
|
||||
}
|
||||
|
||||
if (type_traits<typename type_traits<X>::inner_k_type>::code () != T_void) {
|
||||
mp_inner_k = new ArgType;
|
||||
mp_inner_k->init<typename type_traits<X>::inner_k_type, arg_make_reference> ();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1571,6 +1707,22 @@ public:
|
|||
m_pass_obj = b;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns a value indicating that the value prefers to be copied
|
||||
*/
|
||||
bool prefer_copy () const
|
||||
{
|
||||
return m_prefer_copy;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets a value indicating that the value prefers to be copied
|
||||
*/
|
||||
void set_prefer_copy (bool b)
|
||||
{
|
||||
m_prefer_copy = b;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns a value indicating whether the type is a reference
|
||||
*/
|
||||
|
|
@ -1702,6 +1854,7 @@ private:
|
|||
bool m_is_iter : 1;
|
||||
bool m_owns_spec : 1;
|
||||
bool m_pass_obj : 1;
|
||||
bool m_prefer_copy : 1;
|
||||
mutable const ClassBase *mp_cls;
|
||||
unsigned int m_size;
|
||||
|
||||
|
|
|
|||
|
|
@ -1057,9 +1057,34 @@ static gsi::ClassExt<B> b_ext (
|
|||
gsi::iterator_ext ("b10p", &b10bp_ext, &b10ep_ext)
|
||||
);
|
||||
|
||||
CopyDetector *new_cd (int x)
|
||||
{
|
||||
return new CopyDetector (x);
|
||||
}
|
||||
|
||||
static gsi::Class<CopyDetector> decl_copy_detector ("", "CopyDetector",
|
||||
gsi::constructor ("new", &new_cd) +
|
||||
gsi::method ("x", &CopyDetector::x) +
|
||||
gsi::method ("xx", &CopyDetector::xx)
|
||||
);
|
||||
|
||||
static gsi::Class<C_P> decl_c ("", "C",
|
||||
gsi::callback ("f", &C_P::f, &C_P::f_cb) +
|
||||
gsi::callback ("vfunc", &C_P::vfunc, &C_P::vfunc_cb) +
|
||||
gsi::method ("call_vfunc", &C_P::call_vfunc) +
|
||||
gsi::method ("pass_cd_direct", &C_P::pass_cd_direct) +
|
||||
gsi::method ("pass_cd_cref", &C_P::pass_cd_cref) +
|
||||
gsi::method<C_P, const CopyDetector &, const CopyDetector &, gsi::arg_make_copy> ("pass_cd_cref_as_copy", &C_P::pass_cd_cref) +
|
||||
gsi::method<C_P, const CopyDetector &, const CopyDetector &, gsi::arg_make_reference> ("pass_cd_cref_as_ref", &C_P::pass_cd_cref) +
|
||||
gsi::method ("pass_cd_cptr", &C_P::pass_cd_cptr) +
|
||||
gsi::method<C_P, const CopyDetector *, const CopyDetector &, gsi::arg_make_copy> ("pass_cd_cptr_as_copy", &C_P::pass_cd_cptr) +
|
||||
gsi::method<C_P, const CopyDetector *, const CopyDetector &, gsi::arg_make_reference> ("pass_cd_cptr_as_ref", &C_P::pass_cd_cptr) +
|
||||
gsi::method ("pass_cd_ref", &C_P::pass_cd_ref) +
|
||||
gsi::method<C_P, CopyDetector &, const CopyDetector &, gsi::arg_make_copy> ("pass_cd_ref_as_copy", &C_P::pass_cd_ref) +
|
||||
gsi::method<C_P, CopyDetector &, const CopyDetector &, gsi::arg_make_reference> ("pass_cd_ref_as_ref", &C_P::pass_cd_ref) +
|
||||
gsi::method ("pass_cd_ptr", &C_P::pass_cd_ptr) +
|
||||
gsi::method<C_P, CopyDetector *, const CopyDetector &, gsi::arg_make_copy> ("pass_cd_ptr_as_copy", &C_P::pass_cd_ptr) +
|
||||
gsi::method<C_P, CopyDetector *, const CopyDetector &, gsi::arg_make_reference> ("pass_cd_ptr_as_ref", &C_P::pass_cd_ptr) +
|
||||
gsi::method ("g", &C_P::g) +
|
||||
gsi::method ("s1", &C::s1) +
|
||||
gsi::method ("s2", &C::s2) +
|
||||
|
|
|
|||
|
|
@ -846,6 +846,35 @@ struct B
|
|||
static B *b_inst;
|
||||
};
|
||||
|
||||
class CopyDetector
|
||||
{
|
||||
public:
|
||||
CopyDetector (int x)
|
||||
: m_x (x), m_xx (x)
|
||||
{ }
|
||||
|
||||
CopyDetector ()
|
||||
: m_x (0), m_xx (0)
|
||||
{ }
|
||||
|
||||
CopyDetector (const CopyDetector &d)
|
||||
: m_x (d.m_x), m_xx (d.m_xx + 1) // this detects the copy
|
||||
{ }
|
||||
|
||||
CopyDetector &operator= (const CopyDetector &d)
|
||||
{
|
||||
m_x = d.m_x;
|
||||
m_xx = d.m_xx + 1;
|
||||
return *this;
|
||||
}
|
||||
|
||||
int x () const { return m_x; }
|
||||
int xx () const { return m_xx; }
|
||||
|
||||
private:
|
||||
int m_x, m_xx;
|
||||
};
|
||||
|
||||
class C
|
||||
{
|
||||
public:
|
||||
|
|
@ -861,6 +890,22 @@ public:
|
|||
return f(s);
|
||||
}
|
||||
|
||||
virtual void vfunc (const CopyDetector &)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
void call_vfunc (const CopyDetector &cd)
|
||||
{
|
||||
vfunc (cd);
|
||||
}
|
||||
|
||||
CopyDetector pass_cd_direct (const CopyDetector &cd) { return cd; }
|
||||
const CopyDetector &pass_cd_cref (const CopyDetector &cd) { return cd; }
|
||||
const CopyDetector *pass_cd_cptr (const CopyDetector &cd) { return &cd; }
|
||||
CopyDetector *pass_cd_ptr (const CopyDetector &cd) { return const_cast<CopyDetector *> (&cd); }
|
||||
CopyDetector &pass_cd_ref (const CopyDetector &cd) { return const_cast<CopyDetector &> (cd); }
|
||||
|
||||
static int s1 ();
|
||||
static std::vector<int>::const_iterator s1a ();
|
||||
static std::vector<int>::const_iterator s1b ();
|
||||
|
|
@ -880,7 +925,13 @@ public:
|
|||
return f_cb.can_issue () ? f_cb.issue<C, unsigned int, const std::string &> (&C::f, s) : C::f (s);
|
||||
}
|
||||
|
||||
virtual void vfunc (const CopyDetector &cd)
|
||||
{
|
||||
return vfunc_cb.can_issue () ? vfunc_cb.issue<C, const CopyDetector &> (&C::vfunc, cd) : C::vfunc (cd);
|
||||
}
|
||||
|
||||
gsi::Callback f_cb;
|
||||
gsi::Callback vfunc_cb;
|
||||
};
|
||||
|
||||
struct E
|
||||
|
|
|
|||
|
|
@ -345,7 +345,7 @@ object_to_python (void *obj, PYAObjectBase *self, const gsi::ArgType &atype)
|
|||
bool is_direct = !(atype.is_ptr () || atype.is_ref () || atype.is_cptr () || atype.is_cref ());
|
||||
bool pass_obj = atype.pass_obj () || is_direct;
|
||||
bool is_const = atype.is_cptr () || atype.is_cref ();
|
||||
bool prefer_copy = atype.is_cref ();
|
||||
bool prefer_copy = atype.prefer_copy ();
|
||||
bool can_destroy = prefer_copy || atype.is_ptr ();
|
||||
|
||||
return object_to_python (obj, self, cls, pass_obj, is_const, prefer_copy, can_destroy);
|
||||
|
|
|
|||
|
|
@ -133,7 +133,7 @@ VALUE object_to_ruby (void *obj, Proxy *self, const gsi::ArgType &atype)
|
|||
bool is_direct = !(atype.is_ptr () || atype.is_ref () || atype.is_cptr () || atype.is_cref ());
|
||||
bool pass_obj = atype.pass_obj () || is_direct;
|
||||
bool is_const = atype.is_cptr () || atype.is_cref ();
|
||||
bool prefer_copy = atype.is_cref ();
|
||||
bool prefer_copy = atype.prefer_copy ();
|
||||
bool can_destroy = prefer_copy || atype.is_ptr ();
|
||||
|
||||
return object_to_ruby (obj, self, cls, pass_obj, is_const, prefer_copy, can_destroy);
|
||||
|
|
|
|||
|
|
@ -73,6 +73,14 @@ class C_IMP2(pya.C):
|
|||
class C_IMP3(pya.C):
|
||||
anything = None
|
||||
|
||||
class C_IMP4(pya.C):
|
||||
def __init__(self):
|
||||
self.x = None
|
||||
self.xx = None
|
||||
def vfunc(self, cd):
|
||||
self.x = cd.x()
|
||||
self.xx = cd.xx()
|
||||
|
||||
class Z_IMP1(pya.Z):
|
||||
def f(self, x):
|
||||
return x.cls_name()
|
||||
|
|
@ -1072,6 +1080,11 @@ class BasicTest(unittest.TestCase):
|
|||
arr.append(i)
|
||||
self.assertEqual( arr, [ 0, 1, 2, 3, 4, 5, 6, 0, 0, 1 ] )
|
||||
|
||||
c4 = C_IMP4()
|
||||
c4.call_vfunc(pya.CopyDetector(17))
|
||||
self.assertEqual(c4.x, 17)
|
||||
self.assertEqual(c4.xx, 17)
|
||||
|
||||
def test_20(self):
|
||||
|
||||
b = pya.B()
|
||||
|
|
@ -1538,6 +1551,67 @@ class BasicTest(unittest.TestCase):
|
|||
b = None
|
||||
self.assertEqual(pya.B.has_inst(), False)
|
||||
|
||||
def test_29(self):
|
||||
|
||||
# copy/ref semantics on return
|
||||
|
||||
c = pya.C()
|
||||
|
||||
cd = pya.CopyDetector(42)
|
||||
|
||||
cd2 = c.pass_cd_direct(cd)
|
||||
self.assertEqual(cd2.x(), 42)
|
||||
# two copies: one for return statement and then one for the new object
|
||||
self.assertEqual(cd2.xx(), 44)
|
||||
|
||||
cd2 = c.pass_cd_cref(cd)
|
||||
self.assertEqual(cd2.x(), 42)
|
||||
self.assertEqual(cd2.xx(), 43)
|
||||
|
||||
cd2 = c.pass_cd_cref_as_copy(cd)
|
||||
self.assertEqual(cd2.x(), 42)
|
||||
self.assertEqual(cd2.xx(), 43)
|
||||
|
||||
cd2 = c.pass_cd_cref_as_ref(cd)
|
||||
self.assertEqual(cd2.x(), 42)
|
||||
self.assertEqual(cd2.xx(), 42)
|
||||
|
||||
cd2 = c.pass_cd_cptr(cd)
|
||||
self.assertEqual(cd2.x(), 42)
|
||||
self.assertEqual(cd2.xx(), 42)
|
||||
|
||||
cd2 = c.pass_cd_cptr_as_copy(cd)
|
||||
self.assertEqual(cd2.x(), 42)
|
||||
self.assertEqual(cd2.xx(), 43)
|
||||
|
||||
cd2 = c.pass_cd_cptr_as_ref(cd)
|
||||
self.assertEqual(cd2.x(), 42)
|
||||
self.assertEqual(cd2.xx(), 42)
|
||||
|
||||
cd2 = c.pass_cd_ptr(cd)
|
||||
self.assertEqual(cd2.x(), 42)
|
||||
self.assertEqual(cd2.xx(), 42)
|
||||
|
||||
cd2 = c.pass_cd_ptr_as_copy(cd)
|
||||
self.assertEqual(cd2.x(), 42)
|
||||
self.assertEqual(cd2.xx(), 43)
|
||||
|
||||
cd2 = c.pass_cd_ptr_as_ref(cd)
|
||||
self.assertEqual(cd2.x(), 42)
|
||||
self.assertEqual(cd2.xx(), 42)
|
||||
|
||||
cd2 = c.pass_cd_ref(cd)
|
||||
self.assertEqual(cd2.x(), 42)
|
||||
self.assertEqual(cd2.xx(), 42)
|
||||
|
||||
cd2 = c.pass_cd_ref_as_copy(cd)
|
||||
self.assertEqual(cd2.x(), 42)
|
||||
self.assertEqual(cd2.xx(), 43)
|
||||
|
||||
cd2 = c.pass_cd_ref_as_ref(cd)
|
||||
self.assertEqual(cd2.x(), 42)
|
||||
self.assertEqual(cd2.xx(), 42)
|
||||
|
||||
def test_30(self):
|
||||
|
||||
# some basic tests for the *Value boxing classes
|
||||
|
|
|
|||
|
|
@ -936,6 +936,22 @@ class Basic_TestClass < TestBase
|
|||
class C_IMP3 < RBA::C
|
||||
end
|
||||
|
||||
class C_IMP4 < RBA::C
|
||||
def initialize
|
||||
@x = @xx = nil
|
||||
end
|
||||
def x
|
||||
@x
|
||||
end
|
||||
def xx
|
||||
@xx
|
||||
end
|
||||
def vfunc(cd)
|
||||
@x = cd.x
|
||||
@xx = cd.xx
|
||||
end
|
||||
end
|
||||
|
||||
def test_19
|
||||
|
||||
c0 = RBA::C.new
|
||||
|
|
@ -978,6 +994,11 @@ class Basic_TestClass < TestBase
|
|||
C_IMP2.each { |i| arr.push i }
|
||||
assert_equal( arr, [ 0, 1, 2, 3, 4, 5, 6, 0, 0, 1 ] )
|
||||
|
||||
c4 = C_IMP4.new
|
||||
c4.call_vfunc(RBA::CopyDetector::new(17))
|
||||
assert_equal(c4.x, 17)
|
||||
assert_equal(c4.xx, 17)
|
||||
|
||||
end
|
||||
|
||||
def test_20
|
||||
|
|
@ -1414,6 +1435,69 @@ class Basic_TestClass < TestBase
|
|||
|
||||
end
|
||||
|
||||
def test_29
|
||||
|
||||
# copy/ref semantics on return
|
||||
|
||||
c = RBA::C::new
|
||||
|
||||
cd = RBA::CopyDetector::new(42)
|
||||
|
||||
cd2 = c.pass_cd_direct(cd)
|
||||
assert_equal(cd2.x, 42)
|
||||
# two copies: one for return statement and then one for the new object
|
||||
assert_equal(cd2.xx, 44)
|
||||
|
||||
cd2 = c.pass_cd_cref(cd)
|
||||
assert_equal(cd2.x, 42)
|
||||
assert_equal(cd2.xx, 43)
|
||||
|
||||
cd2 = c.pass_cd_cref_as_copy(cd)
|
||||
assert_equal(cd2.x, 42)
|
||||
assert_equal(cd2.xx, 43)
|
||||
|
||||
cd2 = c.pass_cd_cref_as_ref(cd)
|
||||
assert_equal(cd2.x, 42)
|
||||
assert_equal(cd2.xx, 42)
|
||||
|
||||
cd2 = c.pass_cd_cptr(cd)
|
||||
assert_equal(cd2.x, 42)
|
||||
assert_equal(cd2.xx, 42)
|
||||
|
||||
cd2 = c.pass_cd_cptr_as_copy(cd)
|
||||
assert_equal(cd2.x, 42)
|
||||
assert_equal(cd2.xx, 43)
|
||||
|
||||
cd2 = c.pass_cd_cptr_as_ref(cd)
|
||||
assert_equal(cd2.x, 42)
|
||||
assert_equal(cd2.xx, 42)
|
||||
|
||||
cd2 = c.pass_cd_ptr(cd)
|
||||
assert_equal(cd2.x, 42)
|
||||
assert_equal(cd2.xx, 42)
|
||||
|
||||
cd2 = c.pass_cd_ptr_as_copy(cd)
|
||||
assert_equal(cd2.x, 42)
|
||||
assert_equal(cd2.xx, 43)
|
||||
|
||||
cd2 = c.pass_cd_ptr_as_ref(cd)
|
||||
assert_equal(cd2.x, 42)
|
||||
assert_equal(cd2.xx, 42)
|
||||
|
||||
cd2 = c.pass_cd_ref(cd)
|
||||
assert_equal(cd2.x, 42)
|
||||
assert_equal(cd2.xx, 42)
|
||||
|
||||
cd2 = c.pass_cd_ref_as_copy(cd)
|
||||
assert_equal(cd2.x, 42)
|
||||
assert_equal(cd2.xx, 43)
|
||||
|
||||
cd2 = c.pass_cd_ref_as_ref(cd)
|
||||
assert_equal(cd2.x, 42)
|
||||
assert_equal(cd2.xx, 42)
|
||||
|
||||
end
|
||||
|
||||
def test_30
|
||||
|
||||
# some basic tests for the *Value boxing classes
|
||||
|
|
|
|||
Loading…
Reference in New Issue