mirror of https://github.com/KLayout/klayout.git
commit
19aac2abd7
|
|
@ -30,6 +30,7 @@
|
||||||
#include "tlTypeTraits.h"
|
#include "tlTypeTraits.h"
|
||||||
#include "tlHeap.h"
|
#include "tlHeap.h"
|
||||||
#include "tlUtils.h"
|
#include "tlUtils.h"
|
||||||
|
#include "tlVariant.h"
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
|
@ -76,7 +77,7 @@ struct _var_user_less_impl<T, false>
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief A helper function to implement equal as efficiently as possible
|
* @brief A helper function to implement to_string as efficiently as possible
|
||||||
*/
|
*/
|
||||||
template<class T, bool> struct _var_user_to_string_impl;
|
template<class T, bool> struct _var_user_to_string_impl;
|
||||||
|
|
||||||
|
|
@ -92,6 +93,57 @@ struct _var_user_to_string_impl<T, false>
|
||||||
static std::string call (const T *a, const VariantUserClassImpl *delegate) { return delegate->to_string_impl ((void *) a); }
|
static std::string call (const T *a, const VariantUserClassImpl *delegate) { return delegate->to_string_impl ((void *) a); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief A helper function to implement to_variant as efficiently as possible
|
||||||
|
*/
|
||||||
|
template<class T, bool> struct _var_user_to_variant_impl;
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
struct _var_user_to_variant_impl<T, true>
|
||||||
|
{
|
||||||
|
static tl::Variant call (const T *a, const VariantUserClassImpl * /*delegate*/) { return a->to_variant (); }
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
struct _var_user_to_variant_impl<T, false>
|
||||||
|
{
|
||||||
|
static tl::Variant call (const T *a, const VariantUserClassImpl *delegate) { return delegate->to_variant_impl ((void *) a); }
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief A helper function to implement to_int as efficiently as possible
|
||||||
|
*/
|
||||||
|
template<class T, bool> struct _var_user_to_int_impl;
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
struct _var_user_to_int_impl<T, true>
|
||||||
|
{
|
||||||
|
static int call (const T *a, const VariantUserClassImpl * /*delegate*/) { return a->to_int (); }
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
struct _var_user_to_int_impl<T, false>
|
||||||
|
{
|
||||||
|
static int call (const T *a, const VariantUserClassImpl *delegate) { return delegate->to_int_impl ((void *) a); }
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief A helper function to implement to_double as efficiently as possible
|
||||||
|
*/
|
||||||
|
template<class T, bool> struct _var_user_to_double_impl;
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
struct _var_user_to_double_impl<T, true>
|
||||||
|
{
|
||||||
|
static double call (const T *a, const VariantUserClassImpl * /*delegate*/) { return a->to_double (); }
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
struct _var_user_to_double_impl<T, false>
|
||||||
|
{
|
||||||
|
static double call (const T *a, const VariantUserClassImpl *delegate) { return delegate->to_double_impl ((void *) a); }
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief A VariantUserClassBase specialization that links GSI classes and Variant classes
|
* @brief A VariantUserClassBase specialization that links GSI classes and Variant classes
|
||||||
*/
|
*/
|
||||||
|
|
@ -152,11 +204,26 @@ public:
|
||||||
return gsi::_var_user_less_impl<T, tl::has_less_operator<T>::value>::call ((const T *) a, (const T *) b, this);
|
return gsi::_var_user_less_impl<T, tl::has_less_operator<T>::value>::call ((const T *) a, (const T *) b, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void to_variant (const void *a, tl::Variant &var) const
|
||||||
|
{
|
||||||
|
var = gsi::_var_user_to_variant_impl<T, tl::has_to_variant<T>::value>::call ((const T *) a, this);
|
||||||
|
}
|
||||||
|
|
||||||
virtual std::string to_string (const void *a) const
|
virtual std::string to_string (const void *a) const
|
||||||
{
|
{
|
||||||
return gsi::_var_user_to_string_impl<T, tl::has_to_string<T>::value>::call ((const T *) a, this);
|
return gsi::_var_user_to_string_impl<T, tl::has_to_string<T>::value>::call ((const T *) a, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual int to_int (const void *a) const
|
||||||
|
{
|
||||||
|
return gsi::_var_user_to_int_impl<T, tl::has_to_int<T>::value>::call ((const T *) a, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual double to_double (const void *a) const
|
||||||
|
{
|
||||||
|
return gsi::_var_user_to_double_impl<T, tl::has_to_double<T>::value>::call ((const T *) a, this);
|
||||||
|
}
|
||||||
|
|
||||||
void *clone (const void *obj) const
|
void *clone (const void *obj) const
|
||||||
{
|
{
|
||||||
void *new_obj = mp_cls->create ();
|
void *new_obj = mp_cls->create ();
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@
|
||||||
|
|
||||||
#include "gsiDecl.h"
|
#include "gsiDecl.h"
|
||||||
#include "tlString.h"
|
#include "tlString.h"
|
||||||
|
#include "tlVariant.h"
|
||||||
|
|
||||||
#if defined(HAVE_QT)
|
#if defined(HAVE_QT)
|
||||||
# include <QFlags>
|
# include <QFlags>
|
||||||
|
|
@ -60,6 +61,16 @@ public:
|
||||||
E &value () { return m_e; }
|
E &value () { return m_e; }
|
||||||
const E &value () const { return m_e; }
|
const E &value () const { return m_e; }
|
||||||
|
|
||||||
|
int to_int () const { return int (m_e); }
|
||||||
|
tl::Variant to_variant () const { return tl::Variant (int (m_e)); }
|
||||||
|
|
||||||
|
std::string to_string () const
|
||||||
|
{
|
||||||
|
const Enum<E> *ecls = dynamic_cast<const Enum<E> *> (cls_decl<E> ());
|
||||||
|
tl_assert (ecls != 0);
|
||||||
|
return ecls->enum_to_string (m_e);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
E m_e;
|
E m_e;
|
||||||
};
|
};
|
||||||
|
|
@ -209,7 +220,7 @@ public:
|
||||||
return ecls->enum_to_string_inspect (*e);
|
return ecls->enum_to_string_inspect (*e);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int enum_to_i (const E *e)
|
static int enum_to_int (const E *e)
|
||||||
{
|
{
|
||||||
return int (*e);
|
return int (*e);
|
||||||
}
|
}
|
||||||
|
|
@ -219,16 +230,31 @@ public:
|
||||||
return *e == other;
|
return *e == other;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool enum_eq_with_int (const E *e, int other)
|
||||||
|
{
|
||||||
|
return int (*e) == other;
|
||||||
|
}
|
||||||
|
|
||||||
static bool enum_ne (const E *e, const E &other)
|
static bool enum_ne (const E *e, const E &other)
|
||||||
{
|
{
|
||||||
return *e != other;
|
return *e != other;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool enum_ne_with_int (const E *e, int other)
|
||||||
|
{
|
||||||
|
return int (*e) != other;
|
||||||
|
}
|
||||||
|
|
||||||
static bool enum_lt (const E *e, const E &other)
|
static bool enum_lt (const E *e, const E &other)
|
||||||
{
|
{
|
||||||
return *e < other;
|
return *e < other;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool enum_lt_with_int (const E *e, int other)
|
||||||
|
{
|
||||||
|
return int (*e) < other;
|
||||||
|
}
|
||||||
|
|
||||||
static E *new_enum_from_int (int i)
|
static E *new_enum_from_int (int i)
|
||||||
{
|
{
|
||||||
return new E (E (i));
|
return new E (E (i));
|
||||||
|
|
@ -248,10 +274,13 @@ public:
|
||||||
gsi::constructor ("new", &new_enum_from_string, gsi::arg("s"), "@brief Creates an enum from a string value") +
|
gsi::constructor ("new", &new_enum_from_string, gsi::arg("s"), "@brief Creates an enum from a string value") +
|
||||||
gsi::method_ext ("to_s", &enum_to_string_ext, "@brief Gets the symbolic string from an enum") +
|
gsi::method_ext ("to_s", &enum_to_string_ext, "@brief Gets the symbolic string from an enum") +
|
||||||
gsi::method_ext ("inspect", &enum_to_string_inspect_ext, "@brief Converts an enum to a visual string") +
|
gsi::method_ext ("inspect", &enum_to_string_inspect_ext, "@brief Converts an enum to a visual string") +
|
||||||
gsi::method_ext ("to_i", &enum_to_i, "@brief Gets the integer value from the enum") +
|
gsi::method_ext ("to_i", &enum_to_int, "@brief Gets the integer value from the enum") +
|
||||||
gsi::method_ext ("==", &enum_eq, gsi::arg("other"), "@brief Compares two enums") +
|
gsi::method_ext ("==", &enum_eq, gsi::arg("other"), "@brief Compares two enums") +
|
||||||
|
gsi::method_ext ("==", &enum_eq_with_int, gsi::arg("other"), "@brief Compares an enum with an integer value") +
|
||||||
gsi::method_ext ("!=", &enum_ne, gsi::arg("other"), "@brief Compares two enums for inequality") +
|
gsi::method_ext ("!=", &enum_ne, gsi::arg("other"), "@brief Compares two enums for inequality") +
|
||||||
gsi::method_ext ("<", &enum_lt, gsi::arg("other"), "@brief Returns true if the first enum is less (in the enum symbol order) than the second");
|
gsi::method_ext ("!=", &enum_ne_with_int, gsi::arg("other"), "@brief Compares an enum with an integer for inequality") +
|
||||||
|
gsi::method_ext ("<", &enum_lt, gsi::arg("other"), "@brief Returns true if the first enum is less (in the enum symbol order) than the second") +
|
||||||
|
gsi::method_ext ("<", &enum_lt_with_int, gsi::arg("other"), "@brief Returns true if the enum is less (in the enum symbol order) than the integer value");
|
||||||
|
|
||||||
return m + defs ();
|
return m + defs ();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1241,6 +1241,96 @@ VariantUserClassImpl::to_string_impl (void *obj) const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tl::Variant
|
||||||
|
VariantUserClassImpl::to_variant_impl (void *obj) const
|
||||||
|
{
|
||||||
|
if (obj) {
|
||||||
|
|
||||||
|
if (! has_method ("to_v")) {
|
||||||
|
|
||||||
|
// no method to convert the object to a string
|
||||||
|
return tl::Variant ();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
tl::ExpressionParserContext context;
|
||||||
|
|
||||||
|
tl::Variant out;
|
||||||
|
|
||||||
|
tl::Variant object (obj, mp_object_cls, false);
|
||||||
|
std::vector<tl::Variant> vv;
|
||||||
|
|
||||||
|
execute_gsi (context, out, object, "to_v", vv);
|
||||||
|
|
||||||
|
return out;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
return tl::Variant ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
VariantUserClassImpl::to_int_impl (void *obj) const
|
||||||
|
{
|
||||||
|
if (obj) {
|
||||||
|
|
||||||
|
if (! has_method ("to_i")) {
|
||||||
|
|
||||||
|
// no method to convert the object to an integer
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
tl::ExpressionParserContext context;
|
||||||
|
|
||||||
|
tl::Variant out;
|
||||||
|
|
||||||
|
tl::Variant object (obj, mp_object_cls, false);
|
||||||
|
std::vector<tl::Variant> vv;
|
||||||
|
|
||||||
|
execute_gsi (context, out, object, "to_i", vv);
|
||||||
|
|
||||||
|
return out.to_int ();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
double
|
||||||
|
VariantUserClassImpl::to_double_impl (void *obj) const
|
||||||
|
{
|
||||||
|
if (obj) {
|
||||||
|
|
||||||
|
if (! has_method ("to_f")) {
|
||||||
|
|
||||||
|
// no method to convert the object to a double value
|
||||||
|
return 0.0;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
tl::ExpressionParserContext context;
|
||||||
|
|
||||||
|
tl::Variant out;
|
||||||
|
|
||||||
|
tl::Variant object (obj, mp_object_cls, false);
|
||||||
|
std::vector<tl::Variant> vv;
|
||||||
|
|
||||||
|
execute_gsi (context, out, object, "to_f", vv);
|
||||||
|
|
||||||
|
return out.to_double ();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
VariantUserClassImpl::execute (const tl::ExpressionParserContext &context, tl::Variant &out, tl::Variant &object, const std::string &method, const std::vector<tl::Variant> &args) const
|
VariantUserClassImpl::execute (const tl::ExpressionParserContext &context, tl::Variant &out, tl::Variant &object, const std::string &method, const std::vector<tl::Variant> &args) const
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,10 @@ public:
|
||||||
|
|
||||||
bool equal_impl (void *, void *) const;
|
bool equal_impl (void *, void *) const;
|
||||||
bool less_impl (void *, void *) const;
|
bool less_impl (void *, void *) const;
|
||||||
|
tl::Variant to_variant_impl (void *) const;
|
||||||
std::string to_string_impl (void *) const;
|
std::string to_string_impl (void *) const;
|
||||||
|
int to_int_impl (void *) const;
|
||||||
|
double to_double_impl (void *) const;
|
||||||
|
|
||||||
virtual void execute (const tl::ExpressionParserContext &context, tl::Variant &out, tl::Variant &object, const std::string &method, const std::vector<tl::Variant> &args) const;
|
virtual void execute (const tl::ExpressionParserContext &context, tl::Variant &out, tl::Variant &object, const std::string &method, const std::vector<tl::Variant> &args) const;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1984,6 +1984,9 @@ static std::string get_technology (const lay::CellViewRef *cv)
|
||||||
|
|
||||||
static tl::Event &get_technology_changed_event (lay::CellViewRef *cv)
|
static tl::Event &get_technology_changed_event (lay::CellViewRef *cv)
|
||||||
{
|
{
|
||||||
|
if (! cv->is_valid ()) {
|
||||||
|
throw tl::Exception (tl::to_string (QObject::tr ("Not a valid cellview")));
|
||||||
|
}
|
||||||
return (*cv)->technology_changed_event;
|
return (*cv)->technology_changed_event;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -632,6 +632,14 @@ static std::string extract_python_name (const std::string &name)
|
||||||
static void
|
static void
|
||||||
pya_object_deallocate (PyObject *self)
|
pya_object_deallocate (PyObject *self)
|
||||||
{
|
{
|
||||||
|
// This avoids an assertion in debug builds (Python, gcmodule.c - update_refs).
|
||||||
|
// In short, the GC expects not to see objects with refcount 0 and asserts.
|
||||||
|
// However, due to triggering of signals or similar, the destructor call below
|
||||||
|
// may trigger a GC (https://github.com/KLayout/klayout/issues/1054).
|
||||||
|
// According to the comments this may be turned into a release mode assertion, so
|
||||||
|
// we better work around it.
|
||||||
|
++self->ob_refcnt;
|
||||||
|
|
||||||
PYAObjectBase *p = PYAObjectBase::from_pyobject (self);
|
PYAObjectBase *p = PYAObjectBase::from_pyobject (self);
|
||||||
p->~PYAObjectBase ();
|
p->~PYAObjectBase ();
|
||||||
Py_TYPE (self)->tp_free (self);
|
Py_TYPE (self)->tp_free (self);
|
||||||
|
|
|
||||||
|
|
@ -71,6 +71,18 @@ inline bool value_of (false_tag) { return false; }
|
||||||
typedef char __yes_type [1];
|
typedef char __yes_type [1];
|
||||||
typedef char __no_type [2];
|
typedef char __no_type [2];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Detects whether a class has a "to_variant" method with a matching signature
|
||||||
|
*/
|
||||||
|
template <typename T> static __yes_type &__test_to_variant_func (decltype (&T::to_variant));
|
||||||
|
template <typename> static __no_type &__test_to_variant_func (...);
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct has_to_variant
|
||||||
|
{
|
||||||
|
static constexpr bool value = sizeof (__test_to_variant_func<T> (nullptr)) == sizeof (__yes_type);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Detects whether a class has a "to_string" method with a matching signature
|
* @brief Detects whether a class has a "to_string" method with a matching signature
|
||||||
*/
|
*/
|
||||||
|
|
@ -83,6 +95,30 @@ struct has_to_string
|
||||||
static constexpr bool value = sizeof (__test_to_string_func<T> (nullptr)) == sizeof (__yes_type);
|
static constexpr bool value = sizeof (__test_to_string_func<T> (nullptr)) == sizeof (__yes_type);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Detects whether a class has a "to_int" method with a matching signature
|
||||||
|
*/
|
||||||
|
template <typename T> static __yes_type &__test_to_int_func (decltype (&T::to_int));
|
||||||
|
template <typename> static __no_type &__test_to_int_func (...);
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct has_to_int
|
||||||
|
{
|
||||||
|
static constexpr bool value = sizeof (__test_to_int_func<T> (nullptr)) == sizeof (__yes_type);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Detects whether a class has a "to_double" method with a matching signature
|
||||||
|
*/
|
||||||
|
template <typename T> static __yes_type &__test_to_double_func (decltype (&T::to_double));
|
||||||
|
template <typename> static __no_type &__test_to_double_func (...);
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct has_to_double
|
||||||
|
{
|
||||||
|
static constexpr bool value = sizeof (__test_to_double_func<T> (nullptr)) == sizeof (__yes_type);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Detects whether a class has an equal operator
|
* @brief Detects whether a class has an equal operator
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1820,6 +1820,10 @@ Variant::to_int128 () const
|
||||||
__int128 l = 0;
|
__int128 l = 0;
|
||||||
ex.read (l);
|
ex.read (l);
|
||||||
return l;
|
return l;
|
||||||
|
} else if (m_type == t_user) {
|
||||||
|
return m_var.mp_user.cls->to_int (m_var.mp_user.object);
|
||||||
|
} else if (m_type == t_user_ref) {
|
||||||
|
return m_var.mp_user_ref.cls->to_int (m_var.mp_user_ref.cls->deref_proxy_const (reinterpret_cast <const tl::WeakOrSharedPtr *> (m_var.mp_user_ref.ptr)->get ()));
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -1875,6 +1879,10 @@ Variant::to_ulonglong () const
|
||||||
unsigned long long l = 0;
|
unsigned long long l = 0;
|
||||||
tl::from_string (to_string (), l);
|
tl::from_string (to_string (), l);
|
||||||
return l;
|
return l;
|
||||||
|
} else if (m_type == t_user) {
|
||||||
|
return (unsigned long long) m_var.mp_user.cls->to_int (m_var.mp_user.object);
|
||||||
|
} else if (m_type == t_user_ref) {
|
||||||
|
return (unsigned long long) m_var.mp_user_ref.cls->to_int (m_var.mp_user_ref.cls->deref_proxy_const (reinterpret_cast <const tl::WeakOrSharedPtr *> (m_var.mp_user_ref.ptr)->get ()));
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -1929,6 +1937,10 @@ Variant::to_longlong () const
|
||||||
long long l = 0;
|
long long l = 0;
|
||||||
tl::from_string (to_string (), l);
|
tl::from_string (to_string (), l);
|
||||||
return l;
|
return l;
|
||||||
|
} else if (m_type == t_user) {
|
||||||
|
return (long long) m_var.mp_user.cls->to_int (m_var.mp_user.object);
|
||||||
|
} else if (m_type == t_user_ref) {
|
||||||
|
return (long long) m_var.mp_user_ref.cls->to_int (m_var.mp_user_ref.cls->deref_proxy_const (reinterpret_cast <const tl::WeakOrSharedPtr *> (m_var.mp_user_ref.ptr)->get ()));
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -1983,6 +1995,10 @@ Variant::to_ulong () const
|
||||||
unsigned long l = 0;
|
unsigned long l = 0;
|
||||||
tl::from_string (to_string (), l);
|
tl::from_string (to_string (), l);
|
||||||
return l;
|
return l;
|
||||||
|
} else if (m_type == t_user) {
|
||||||
|
return (unsigned long) m_var.mp_user.cls->to_int (m_var.mp_user.object);
|
||||||
|
} else if (m_type == t_user_ref) {
|
||||||
|
return (unsigned long) m_var.mp_user_ref.cls->to_int (m_var.mp_user_ref.cls->deref_proxy_const (reinterpret_cast <const tl::WeakOrSharedPtr *> (m_var.mp_user_ref.ptr)->get ()));
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -2037,6 +2053,10 @@ Variant::to_long () const
|
||||||
long l = 0;
|
long l = 0;
|
||||||
tl::from_string (to_string (), l);
|
tl::from_string (to_string (), l);
|
||||||
return l;
|
return l;
|
||||||
|
} else if (m_type == t_user) {
|
||||||
|
return (long) m_var.mp_user.cls->to_int (m_var.mp_user.object);
|
||||||
|
} else if (m_type == t_user_ref) {
|
||||||
|
return (long) m_var.mp_user_ref.cls->to_int (m_var.mp_user_ref.cls->deref_proxy_const (reinterpret_cast <const tl::WeakOrSharedPtr *> (m_var.mp_user_ref.ptr)->get ()));
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -2143,6 +2163,10 @@ Variant::to_double () const
|
||||||
double d = 0;
|
double d = 0;
|
||||||
tl::from_string (to_string (), d);
|
tl::from_string (to_string (), d);
|
||||||
return d;
|
return d;
|
||||||
|
} else if (m_type == t_user) {
|
||||||
|
return m_var.mp_user.cls->to_double (m_var.mp_user.object);
|
||||||
|
} else if (m_type == t_user_ref) {
|
||||||
|
return m_var.mp_user_ref.cls->to_double (m_var.mp_user_ref.cls->deref_proxy_const (reinterpret_cast <const tl::WeakOrSharedPtr *> (m_var.mp_user_ref.ptr)->get ()));
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -2513,7 +2537,9 @@ QVariant Variant::to_qvariant () const
|
||||||
} else if (dynamic_cast<const tl::VariantUserClass<QVector4D> *> (cls)) {
|
} else if (dynamic_cast<const tl::VariantUserClass<QVector4D> *> (cls)) {
|
||||||
return QVariant (to_user<QVector4D> ());
|
return QVariant (to_user<QVector4D> ());
|
||||||
} else {
|
} else {
|
||||||
return QVariant ();
|
tl::Variant var;
|
||||||
|
cls->to_variant (to_user (), var);
|
||||||
|
return var.to_qvariant ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,7 @@ namespace gsi
|
||||||
namespace tl
|
namespace tl
|
||||||
{
|
{
|
||||||
|
|
||||||
|
class Variant;
|
||||||
class Extractor;
|
class Extractor;
|
||||||
class EvalClass;
|
class EvalClass;
|
||||||
template <class T> void extractor_impl (tl::Extractor &, T &);
|
template <class T> void extractor_impl (tl::Extractor &, T &);
|
||||||
|
|
@ -76,6 +77,9 @@ public:
|
||||||
virtual bool less (const void *, const void *) const = 0;
|
virtual bool less (const void *, const void *) const = 0;
|
||||||
virtual void *clone (const void *) const = 0;
|
virtual void *clone (const void *) const = 0;
|
||||||
virtual std::string to_string (const void *) const = 0;
|
virtual std::string to_string (const void *) const = 0;
|
||||||
|
virtual int to_int (const void *) const = 0;
|
||||||
|
virtual double to_double (const void *) const = 0;
|
||||||
|
virtual void to_variant (const void *, tl::Variant &var) const = 0;
|
||||||
virtual void read (void *, tl::Extractor &ex) const = 0;
|
virtual void read (void *, tl::Extractor &ex) const = 0;
|
||||||
virtual const char *name () const = 0;
|
virtual const char *name () const = 0;
|
||||||
virtual bool is_const () const = 0;
|
virtual bool is_const () const = 0;
|
||||||
|
|
|
||||||
|
|
@ -119,6 +119,57 @@ struct _var_user_to_string_impl<T, false>
|
||||||
static std::string call (const T *) { tl_assert (false); }
|
static std::string call (const T *) { tl_assert (false); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief A helper function to implement equal as efficiently as possible
|
||||||
|
*/
|
||||||
|
template<class T, bool> struct _var_user_to_int_impl;
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
struct _var_user_to_int_impl<T, true>
|
||||||
|
{
|
||||||
|
static int call (const T *a) { return a->to_int (); }
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
struct _var_user_to_int_impl<T, false>
|
||||||
|
{
|
||||||
|
static int call (const T *) { tl_assert (false); }
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief A helper function to implement equal as efficiently as possible
|
||||||
|
*/
|
||||||
|
template<class T, bool> struct _var_user_to_double_impl;
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
struct _var_user_to_double_impl<T, true>
|
||||||
|
{
|
||||||
|
static double call (const T *a) { return a->to_double (); }
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
struct _var_user_to_double_impl<T, false>
|
||||||
|
{
|
||||||
|
static double call (const T *) { tl_assert (false); }
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief A helper function to implement equal as efficiently as possible
|
||||||
|
*/
|
||||||
|
template<class T, bool> struct _var_user_to_variant_impl;
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
struct _var_user_to_variant_impl<T, true>
|
||||||
|
{
|
||||||
|
static tl::Variant call (const T *a) { return a->to_variant (); }
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
struct _var_user_to_variant_impl<T, false>
|
||||||
|
{
|
||||||
|
static tl::Variant call (const T *) { tl_assert (false); }
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief A utility implementation of tl::VariantUserClass using type traits for the implementation
|
* @brief A utility implementation of tl::VariantUserClass using type traits for the implementation
|
||||||
*/
|
*/
|
||||||
|
|
@ -162,6 +213,21 @@ public:
|
||||||
return _var_user_to_string_impl<T, tl::has_to_string<T>::value>::call ((const T *) a);
|
return _var_user_to_string_impl<T, tl::has_to_string<T>::value>::call ((const T *) a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual int to_int (const void *a) const
|
||||||
|
{
|
||||||
|
return _var_user_to_int_impl<T, tl::has_to_int<T>::value>::call ((const T *) a);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual double to_double (const void *a) const
|
||||||
|
{
|
||||||
|
return _var_user_to_double_impl<T, tl::has_to_double<T>::value>::call ((const T *) a);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void to_variant (const void *a, tl::Variant &v) const
|
||||||
|
{
|
||||||
|
v = _var_user_to_variant_impl<T, tl::has_to_variant<T>::value>::call ((const T *) a);
|
||||||
|
}
|
||||||
|
|
||||||
virtual void read (void *a, tl::Extractor &ex) const
|
virtual void read (void *a, tl::Extractor &ex) const
|
||||||
{
|
{
|
||||||
ex.read (*(T *)a);
|
ex.read (*(T *)a);
|
||||||
|
|
|
||||||
|
|
@ -454,6 +454,9 @@ public:
|
||||||
virtual void *clone (const void *) const { tl_assert (false); }
|
virtual void *clone (const void *) const { tl_assert (false); }
|
||||||
virtual void assign (void *, const void *) const { tl_assert (false); }
|
virtual void assign (void *, const void *) const { tl_assert (false); }
|
||||||
virtual std::string to_string (const void *) const { tl_assert (false); }
|
virtual std::string to_string (const void *) const { tl_assert (false); }
|
||||||
|
virtual int to_int (const void *) const { tl_assert (false); }
|
||||||
|
virtual double to_double (const void *) const { tl_assert (false); }
|
||||||
|
virtual void to_variant (const void *, tl::Variant &) const { tl_assert (false); }
|
||||||
virtual void read (void *, tl::Extractor &) const { }
|
virtual void read (void *, tl::Extractor &) const { }
|
||||||
virtual const char *name () const { return "Box"; }
|
virtual const char *name () const { return "Box"; }
|
||||||
virtual unsigned int type_code () const { return 0; }
|
virtual unsigned int type_code () const { return 0; }
|
||||||
|
|
@ -519,6 +522,9 @@ public:
|
||||||
virtual void *clone (const void *) const { tl_assert (false); }
|
virtual void *clone (const void *) const { tl_assert (false); }
|
||||||
virtual void assign (void *, const void *) const { tl_assert (false); }
|
virtual void assign (void *, const void *) const { tl_assert (false); }
|
||||||
virtual std::string to_string (const void *) const { tl_assert (false); }
|
virtual std::string to_string (const void *) const { tl_assert (false); }
|
||||||
|
virtual int to_int (const void *) const { tl_assert (false); }
|
||||||
|
virtual double to_double (const void *) const { tl_assert (false); }
|
||||||
|
virtual void to_variant (const void *, tl::Variant &) const { tl_assert (false); }
|
||||||
virtual void read (void *, tl::Extractor &) const { }
|
virtual void read (void *, tl::Extractor &) const { }
|
||||||
virtual const char *name () const { return "Edge"; }
|
virtual const char *name () const { return "Edge"; }
|
||||||
virtual unsigned int type_code () const { return 0; }
|
virtual unsigned int type_code () const { return 0; }
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue