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)
|
* @brief Adds an argument to the argument list (of type X)
|
||||||
*/
|
*/
|
||||||
template <class X>
|
template <class X>
|
||||||
void add_arg ()
|
void add_arg ()
|
||||||
{
|
{
|
||||||
ArgType a;
|
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_arg_types.push_back (a);
|
||||||
m_argsize += a.size ();
|
m_argsize += a.size ();
|
||||||
}
|
}
|
||||||
|
|
@ -346,11 +358,23 @@ public:
|
||||||
/**
|
/**
|
||||||
* @brief Adds an argument to the argument list (of type X plus additional specs)
|
* @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)
|
void add_arg (const ArgSpecBase &spec)
|
||||||
{
|
{
|
||||||
ArgType a;
|
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_arg_types.push_back (a);
|
||||||
m_argsize += a.size ();
|
m_argsize += a.size ();
|
||||||
}
|
}
|
||||||
|
|
@ -358,11 +382,23 @@ public:
|
||||||
/**
|
/**
|
||||||
* @brief This version will take the ownership of the ArgSpecBase object
|
* @brief This version will take the ownership of the ArgSpecBase object
|
||||||
*/
|
*/
|
||||||
template <class X>
|
template <class X>
|
||||||
void add_arg (ArgSpecBase *spec)
|
void add_arg (ArgSpecBase *spec)
|
||||||
{
|
{
|
||||||
ArgType a;
|
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_arg_types.push_back (a);
|
||||||
m_argsize += a.size ();
|
m_argsize += a.size ();
|
||||||
}
|
}
|
||||||
|
|
@ -379,10 +415,19 @@ public:
|
||||||
/**
|
/**
|
||||||
* @brief Sets the return type to "X"
|
* @brief Sets the return type to "X"
|
||||||
*/
|
*/
|
||||||
template <class X>
|
template <class X>
|
||||||
void set_return ()
|
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>
|
template <class X>
|
||||||
void set_return_new ()
|
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));
|
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
|
// 0 argument
|
||||||
|
|
||||||
#define _COUNT 0
|
#define _COUNT 0
|
||||||
|
|
|
||||||
|
|
@ -220,7 +220,7 @@ private:
|
||||||
_ARGSPECMEM
|
_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)
|
class _NAME(Method)
|
||||||
: public MethodSpecificBase <X>
|
: public MethodSpecificBase <X>
|
||||||
{
|
{
|
||||||
|
|
@ -240,11 +240,7 @@ public:
|
||||||
{
|
{
|
||||||
this->clear ();
|
this->clear ();
|
||||||
_ADDARGS
|
_ADDARGS
|
||||||
if (tl::value_from_type (typename F::is_factory ())) {
|
this->template set_return<R, Transfer> ();
|
||||||
this->template set_return_new<R> ();
|
|
||||||
} else {
|
|
||||||
this->template set_return<R> ();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual MethodBase *clone () const
|
virtual MethodBase *clone () const
|
||||||
|
|
@ -268,7 +264,7 @@ private:
|
||||||
_ARGSPECMEM
|
_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)
|
class _NAME(ConstMethod)
|
||||||
: public MethodSpecificBase <X>
|
: public MethodSpecificBase <X>
|
||||||
{
|
{
|
||||||
|
|
@ -288,11 +284,7 @@ public:
|
||||||
{
|
{
|
||||||
this->clear ();
|
this->clear ();
|
||||||
_ADDARGS
|
_ADDARGS
|
||||||
if (tl::value_from_type (typename F::is_factory ())) {
|
this->template set_return<R, Transfer> ();
|
||||||
this->template set_return_new<R> ();
|
|
||||||
} else {
|
|
||||||
this->template set_return<R> ();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual MethodBase *clone () const
|
virtual MethodBase *clone () const
|
||||||
|
|
@ -316,7 +308,7 @@ private:
|
||||||
_ARGSPECMEM
|
_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)
|
class _NAME(ExtMethod)
|
||||||
: public MethodBase
|
: public MethodBase
|
||||||
{
|
{
|
||||||
|
|
@ -336,11 +328,7 @@ public:
|
||||||
{
|
{
|
||||||
this->clear ();
|
this->clear ();
|
||||||
_ADDARGS
|
_ADDARGS
|
||||||
if (tl::value_from_type (typename F::is_factory ())) {
|
this->template set_return<R, Transfer> ();
|
||||||
this->template set_return_new<R> ();
|
|
||||||
} else {
|
|
||||||
this->template set_return<R> ();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual MethodBase *clone () const
|
virtual MethodBase *clone () const
|
||||||
|
|
@ -364,7 +352,7 @@ private:
|
||||||
_ARGSPECMEM
|
_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)
|
class _NAME(StaticMethod)
|
||||||
: public StaticMethodBase
|
: public StaticMethodBase
|
||||||
{
|
{
|
||||||
|
|
@ -384,11 +372,7 @@ public:
|
||||||
{
|
{
|
||||||
this->clear ();
|
this->clear ();
|
||||||
_ADDARGS
|
_ADDARGS
|
||||||
if (tl::value_from_type (typename F::is_factory ())) {
|
this->template set_return<R, Transfer> ();
|
||||||
this->template set_return_new<R> ();
|
|
||||||
} else {
|
|
||||||
this->template set_return<R> ();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual MethodBase *clone () const
|
virtual MethodBase *clone () const
|
||||||
|
|
@ -1300,7 +1284,14 @@ template <class X, class R _COMMA _TMPLARG>
|
||||||
Methods
|
Methods
|
||||||
method (const std::string &name, R (X::*m) (_FUNCARGLIST), const std::string &doc = std::string ())
|
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
|
#if _COUNT != 0
|
||||||
|
|
@ -1308,7 +1299,14 @@ template <class X, class R _COMMA _TMPLARG _COMMA _TMPLARGSPECS>
|
||||||
Methods
|
Methods
|
||||||
method (const std::string &name, R (X::*m) (_FUNCARGLIST) _COMMA _ARGSPECS, const std::string &doc = std::string ())
|
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
|
#endif
|
||||||
|
|
||||||
|
|
@ -1316,7 +1314,7 @@ template <class X, class R _COMMA _TMPLARG>
|
||||||
Methods
|
Methods
|
||||||
factory (const std::string &name, R *(X::*m) (_FUNCARGLIST), const std::string &doc = std::string ())
|
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
|
#if _COUNT != 0
|
||||||
|
|
@ -1324,7 +1322,7 @@ template <class X, class R _COMMA _TMPLARG _COMMA _TMPLARGSPECS>
|
||||||
Methods
|
Methods
|
||||||
factory (const std::string &name, R *(X::*m) (_FUNCARGLIST) _COMMA _ARGSPECS, const std::string &doc = std::string ())
|
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
|
#endif
|
||||||
|
|
||||||
|
|
@ -1332,7 +1330,14 @@ template <class X, class R _COMMA _TMPLARG>
|
||||||
Methods
|
Methods
|
||||||
method_ext (const std::string &name, R (*xm) (X * _COMMA _FUNCARGLIST), const std::string &doc = std::string ())
|
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
|
#if _COUNT != 0
|
||||||
|
|
@ -1340,7 +1345,14 @@ template <class X, class R _COMMA _TMPLARG _COMMA _TMPLARGSPECS>
|
||||||
Methods
|
Methods
|
||||||
method_ext (const std::string &name, R (*xm) (X * _COMMA _FUNCARGLIST) _COMMA _ARGSPECS, const std::string &doc = std::string ())
|
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
|
#endif
|
||||||
|
|
||||||
|
|
@ -1348,7 +1360,7 @@ template <class X, class R _COMMA _TMPLARG>
|
||||||
Methods
|
Methods
|
||||||
factory_ext (const std::string &name, R *(*xm) (X * _COMMA _FUNCARGLIST), const std::string &doc = std::string ())
|
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
|
#if _COUNT != 0
|
||||||
|
|
@ -1356,7 +1368,7 @@ template <class X, class R _COMMA _TMPLARG _COMMA _TMPLARGSPECS>
|
||||||
Methods
|
Methods
|
||||||
factory_ext (const std::string &name, R *(*xm) (X * _COMMA _FUNCARGLIST) _COMMA _ARGSPECS, const std::string &doc = std::string ())
|
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
|
#endif
|
||||||
|
|
||||||
|
|
@ -1364,7 +1376,7 @@ template <class X _COMMA _TMPLARG>
|
||||||
Methods
|
Methods
|
||||||
constructor (const std::string &name, X *(*m) (_FUNCARGLIST), const std::string &doc = std::string ())
|
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
|
#if _COUNT != 0
|
||||||
|
|
@ -1372,7 +1384,7 @@ template <class X _COMMA _TMPLARG _COMMA _TMPLARGSPECS>
|
||||||
Methods
|
Methods
|
||||||
constructor (const std::string &name, X *(*m) (_FUNCARGLIST) _COMMA _ARGSPECS, const std::string &doc = std::string ())
|
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
|
#endif
|
||||||
|
|
||||||
|
|
@ -1380,7 +1392,14 @@ template <class R _COMMA _TMPLARG>
|
||||||
Methods
|
Methods
|
||||||
method (const std::string &name, R (*m) (_FUNCARGLIST), const std::string &doc = std::string ())
|
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
|
#if _COUNT != 0
|
||||||
|
|
@ -1388,7 +1407,14 @@ template <class R _COMMA _TMPLARG _COMMA _TMPLARGSPECS>
|
||||||
Methods
|
Methods
|
||||||
method (const std::string &name, R (*m) (_FUNCARGLIST) _COMMA _ARGSPECS, const std::string &doc = std::string ())
|
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
|
#endif
|
||||||
|
|
||||||
|
|
@ -1396,7 +1422,7 @@ template <class R _COMMA _TMPLARG>
|
||||||
Methods
|
Methods
|
||||||
factory (const std::string &name, R *(*m) (_FUNCARGLIST), const std::string &doc = std::string ())
|
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
|
#if _COUNT != 0
|
||||||
|
|
@ -1404,7 +1430,7 @@ template <class R _COMMA _TMPLARG _COMMA _TMPLARGSPECS>
|
||||||
Methods
|
Methods
|
||||||
factory (const std::string &name, R *(*m) (_FUNCARGLIST) _COMMA _ARGSPECS, const std::string &doc = std::string ())
|
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
|
#endif
|
||||||
|
|
||||||
|
|
@ -1428,7 +1454,7 @@ template <class X, class R _COMMA _TMPLARG>
|
||||||
Methods
|
Methods
|
||||||
factory_callback (const std::string &name, R (X::*m) (_FUNCARGLIST), Callback X::*cb, const std::string &doc = std::string ())
|
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
|
#if _COUNT != 0
|
||||||
|
|
@ -1436,7 +1462,7 @@ template <class X, class R _COMMA _TMPLARG _COMMA _TMPLARGSPECS>
|
||||||
Methods
|
Methods
|
||||||
factory_callback (const std::string &name, R (X::*m) (_FUNCARGLIST), Callback X::*cb _COMMA _ARGSPECS, const std::string &doc = std::string ())
|
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
|
#endif
|
||||||
|
|
||||||
|
|
@ -1444,7 +1470,14 @@ template <class X, class R _COMMA _TMPLARG>
|
||||||
Methods
|
Methods
|
||||||
method (const std::string &name, R (X::*m) (_FUNCARGLIST) const, const std::string &doc = std::string ())
|
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
|
#if _COUNT != 0
|
||||||
|
|
@ -1452,7 +1485,14 @@ template <class X, class R _COMMA _TMPLARG _COMMA _TMPLARGSPECS>
|
||||||
Methods
|
Methods
|
||||||
method (const std::string &name, R (X::*m) (_FUNCARGLIST) const _COMMA _ARGSPECS, const std::string &doc = std::string ())
|
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
|
#endif
|
||||||
|
|
||||||
|
|
@ -1460,7 +1500,7 @@ template <class X, class R _COMMA _TMPLARG>
|
||||||
Methods
|
Methods
|
||||||
factory (const std::string &name, R *(X::*m) (_FUNCARGLIST) const, const std::string &doc = std::string ())
|
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
|
#if _COUNT != 0
|
||||||
|
|
@ -1468,7 +1508,7 @@ template <class X, class R _COMMA _TMPLARG _COMMA _TMPLARGSPECS>
|
||||||
Methods
|
Methods
|
||||||
factory (const std::string &name, R *(X::*m) (_FUNCARGLIST) const _COMMA _ARGSPECS, const std::string &doc = std::string ())
|
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
|
#endif
|
||||||
|
|
||||||
|
|
@ -1492,7 +1532,7 @@ template <class X, class R _COMMA _TMPLARG>
|
||||||
Methods
|
Methods
|
||||||
factory_callback (const std::string &name, R (X::*m) (_FUNCARGLIST) const, Callback X::*cb, const std::string &doc = std::string ())
|
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
|
#if _COUNT != 0
|
||||||
|
|
@ -1500,7 +1540,7 @@ template <class X, class R _COMMA _TMPLARG _COMMA _TMPLARGSPECS>
|
||||||
Methods
|
Methods
|
||||||
factory_callback (const std::string &name, R (X::*m) (_FUNCARGLIST) const, Callback X::*cb _COMMA _ARGSPECS, const std::string &doc = std::string ())
|
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
|
#endif
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -112,7 +112,7 @@ ArgType::to_string () const
|
||||||
ArgType::ArgType ()
|
ArgType::ArgType ()
|
||||||
: m_type (T_void), mp_spec (0), mp_inner (0), mp_inner_k (0),
|
: 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_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)
|
mp_cls (0), m_size (0)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
|
@ -132,7 +132,7 @@ ArgType::~ArgType ()
|
||||||
ArgType::ArgType (const ArgType &other)
|
ArgType::ArgType (const ArgType &other)
|
||||||
: m_type (T_void), mp_spec (0), mp_inner (0), mp_inner_k (0),
|
: 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_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)
|
mp_cls (0), m_size (0)
|
||||||
{
|
{
|
||||||
operator= (other);
|
operator= (other);
|
||||||
|
|
@ -156,6 +156,7 @@ ArgType::operator= (const ArgType &other)
|
||||||
|
|
||||||
m_type = other.m_type;
|
m_type = other.m_type;
|
||||||
m_pass_obj = other.m_pass_obj;
|
m_pass_obj = other.m_pass_obj;
|
||||||
|
m_prefer_copy = other.m_prefer_copy;
|
||||||
m_is_ref = other.m_is_ref;
|
m_is_ref = other.m_is_ref;
|
||||||
m_is_cref = other.m_is_cref;
|
m_is_cref = other.m_is_cref;
|
||||||
m_is_ptr = other.m_is_ptr;
|
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 &&
|
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 &&
|
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
|
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
|
* @brief Generic argument type declaration
|
||||||
*
|
*
|
||||||
|
|
@ -1427,7 +1488,22 @@ public:
|
||||||
template <class X>
|
template <class X>
|
||||||
void init (const ArgSpecBase &spec)
|
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;
|
mp_spec = &spec;
|
||||||
m_owns_spec = false;
|
m_owns_spec = false;
|
||||||
}
|
}
|
||||||
|
|
@ -1442,7 +1518,22 @@ public:
|
||||||
template <class X>
|
template <class X>
|
||||||
void init (ArgSpecBase *spec)
|
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;
|
mp_spec = spec;
|
||||||
m_owns_spec = true;
|
m_owns_spec = true;
|
||||||
}
|
}
|
||||||
|
|
@ -1454,7 +1545,7 @@ public:
|
||||||
* to the case of object pointers mainly.
|
* to the case of object pointers mainly.
|
||||||
*/
|
*/
|
||||||
template <class X>
|
template <class X>
|
||||||
void init (bool pass_obj = false)
|
void init ()
|
||||||
{
|
{
|
||||||
release_spec ();
|
release_spec ();
|
||||||
|
|
||||||
|
|
@ -1462,7 +1553,8 @@ public:
|
||||||
m_is_iter = type_traits<X>::is_iter ();
|
m_is_iter = type_traits<X>::is_iter ();
|
||||||
mp_cls = type_traits<X>::cls_decl ();
|
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_ref = type_traits<X>::is_ref ();
|
||||||
m_is_ptr = type_traits<X>::is_ptr ();
|
m_is_ptr = type_traits<X>::is_ptr ();
|
||||||
m_is_cref = type_traits<X>::is_cref ();
|
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) {
|
if (type_traits<typename type_traits<X>::inner_type>::code () != T_void) {
|
||||||
mp_inner = new ArgType;
|
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) {
|
if (type_traits<typename type_traits<X>::inner_k_type>::code () != T_void) {
|
||||||
mp_inner_k = new ArgType;
|
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;
|
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
|
* @brief Returns a value indicating whether the type is a reference
|
||||||
*/
|
*/
|
||||||
|
|
@ -1702,6 +1854,7 @@ private:
|
||||||
bool m_is_iter : 1;
|
bool m_is_iter : 1;
|
||||||
bool m_owns_spec : 1;
|
bool m_owns_spec : 1;
|
||||||
bool m_pass_obj : 1;
|
bool m_pass_obj : 1;
|
||||||
|
bool m_prefer_copy : 1;
|
||||||
mutable const ClassBase *mp_cls;
|
mutable const ClassBase *mp_cls;
|
||||||
unsigned int m_size;
|
unsigned int m_size;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1057,9 +1057,34 @@ static gsi::ClassExt<B> b_ext (
|
||||||
gsi::iterator_ext ("b10p", &b10bp_ext, &b10ep_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",
|
static gsi::Class<C_P> decl_c ("", "C",
|
||||||
gsi::callback ("f", &C_P::f, &C_P::f_cb) +
|
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 ("g", &C_P::g) +
|
||||||
gsi::method ("s1", &C::s1) +
|
gsi::method ("s1", &C::s1) +
|
||||||
gsi::method ("s2", &C::s2) +
|
gsi::method ("s2", &C::s2) +
|
||||||
|
|
|
||||||
|
|
@ -846,6 +846,35 @@ struct B
|
||||||
static B *b_inst;
|
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
|
class C
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
@ -861,6 +890,22 @@ public:
|
||||||
return f(s);
|
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 int s1 ();
|
||||||
static std::vector<int>::const_iterator s1a ();
|
static std::vector<int>::const_iterator s1a ();
|
||||||
static std::vector<int>::const_iterator s1b ();
|
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);
|
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 f_cb;
|
||||||
|
gsi::Callback vfunc_cb;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct E
|
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 is_direct = !(atype.is_ptr () || atype.is_ref () || atype.is_cptr () || atype.is_cref ());
|
||||||
bool pass_obj = atype.pass_obj () || is_direct;
|
bool pass_obj = atype.pass_obj () || is_direct;
|
||||||
bool is_const = atype.is_cptr () || atype.is_cref ();
|
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 ();
|
bool can_destroy = prefer_copy || atype.is_ptr ();
|
||||||
|
|
||||||
return object_to_python (obj, self, cls, pass_obj, is_const, prefer_copy, can_destroy);
|
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 is_direct = !(atype.is_ptr () || atype.is_ref () || atype.is_cptr () || atype.is_cref ());
|
||||||
bool pass_obj = atype.pass_obj () || is_direct;
|
bool pass_obj = atype.pass_obj () || is_direct;
|
||||||
bool is_const = atype.is_cptr () || atype.is_cref ();
|
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 ();
|
bool can_destroy = prefer_copy || atype.is_ptr ();
|
||||||
|
|
||||||
return object_to_ruby (obj, self, cls, pass_obj, is_const, prefer_copy, can_destroy);
|
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):
|
class C_IMP3(pya.C):
|
||||||
anything = None
|
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):
|
class Z_IMP1(pya.Z):
|
||||||
def f(self, x):
|
def f(self, x):
|
||||||
return x.cls_name()
|
return x.cls_name()
|
||||||
|
|
@ -1072,6 +1080,11 @@ class BasicTest(unittest.TestCase):
|
||||||
arr.append(i)
|
arr.append(i)
|
||||||
self.assertEqual( arr, [ 0, 1, 2, 3, 4, 5, 6, 0, 0, 1 ] )
|
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):
|
def test_20(self):
|
||||||
|
|
||||||
b = pya.B()
|
b = pya.B()
|
||||||
|
|
@ -1538,6 +1551,67 @@ class BasicTest(unittest.TestCase):
|
||||||
b = None
|
b = None
|
||||||
self.assertEqual(pya.B.has_inst(), False)
|
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):
|
def test_30(self):
|
||||||
|
|
||||||
# some basic tests for the *Value boxing classes
|
# some basic tests for the *Value boxing classes
|
||||||
|
|
|
||||||
|
|
@ -936,6 +936,22 @@ class Basic_TestClass < TestBase
|
||||||
class C_IMP3 < RBA::C
|
class C_IMP3 < RBA::C
|
||||||
end
|
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
|
def test_19
|
||||||
|
|
||||||
c0 = RBA::C.new
|
c0 = RBA::C.new
|
||||||
|
|
@ -978,6 +994,11 @@ class Basic_TestClass < TestBase
|
||||||
C_IMP2.each { |i| arr.push i }
|
C_IMP2.each { |i| arr.push i }
|
||||||
assert_equal( arr, [ 0, 1, 2, 3, 4, 5, 6, 0, 0, 1 ] )
|
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
|
end
|
||||||
|
|
||||||
def test_20
|
def test_20
|
||||||
|
|
@ -1414,6 +1435,69 @@ class Basic_TestClass < TestBase
|
||||||
|
|
||||||
end
|
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
|
def test_30
|
||||||
|
|
||||||
# some basic tests for the *Value boxing classes
|
# some basic tests for the *Value boxing classes
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue