If I have a class defined as follows in C++
class sample
{
private:
int data;
public:
sample()
{
data=0;
}
int get_data()
{
return data;
}
void set_data(int data)
{
this->data = data;
}
};
and I want to expose it to cython code using:
cdef extern from "sample.cpp":
cdef cppclass sample:
sample() except +
int get_data()
void set_data(int n)
Is there a way to expose the getter and setter in that class in such a way that they can then be used in cython using syntax such as:
a = obj.data
instead of
a = obj.get_data()
I know it is possible to do that by wrapping the class in cython defined class, but I would like to avoid that avoid that overhead.
Maybe I am asking for too much.
Disclaimer: I don't know cython, so I cannot say if the following will be fine for cython. However, my strategy would be to implement access via s.data already in the C++ code to keep the bindings slim and straightforward.
C++ has no attributes, but one can emulate them:
#include <iostream>
template <typename T,typename M,M (T::*getter)(),void (T::*setter)(M)>
struct Attribute {
T* parent;
Attribute(T* parent) : parent(parent){}
operator M() const {
return (parent->*getter)();
}
void operator=(const M& m){
(parent->*setter)(m);
}
};
class sample
{
private:
int data_;
public:
sample()
{
data_=0;
}
int get_data()
{
return data_;
}
void set_data(int data_)
{
this->data_ = data_;
}
Attribute<sample,int,&sample::get_data,&sample::set_data> data{this};
};
int main() {
sample s;
s.data = 42;
std::cout << s.data;
}
Output is 42. Note that I had to assume a int parameter for the setter. To enable also const int& a bit more will be needed.
Using the definition of the sample c++ class in the accepted response above by #idclev 463035818, and copied here for convenience:
#include <iostream>
template <typename T,typename M,M (T::*getter)(),void (T::*setter)(M)>
struct Attribute {
T* parent;
Attribute(T* parent) : parent(parent){}
operator M() const {
return (parent->*getter)();
}
void operator=(const M& m){
(parent->*setter)(m);
}
};
class sample
{
private:
int data_;
public:
sample()
{
data_=0;
}
int get_data()
{
return data_;
}
void set_data(int data_)
{
this->data_ = data_;
}
Attribute<sample,int,&sample::get_data,&sample::set_data> data{this};
};
I tested declaring that C++ class in cython with a flat public property, and ... it works! This does the job.
cdef extern from "sample.cpp":
cdef cppclass sample:
sample() except +
int data
Testing that and instrumenting the accessors in the example shows that the accessors are properly called.
Many thanks to everyone! That was very helpful.
Related
I am working on a plugin that runs inside a host program against a proprietary PDK. At times there will be breaking changes in the PDK, so my code uses wrapper classes that allow it to work with more than one version of the host while encapsulating the changes from version to version.
Here is a very simplified example that illustrates the kind of issue I would like to address. Of course, I'm dealing with many more members that 2.
struct DataV1 // I cannot modify this
{
int a;
float b;
};
struct DataV2 // I cannot modify this
{
float b;
int a;
long c;
};
class DataWrapper // my class
{
private:
bool _forV1; // determined at run-time
DataV1 _dataV1;
DataV2 _dataV2;
public:
DataWrapper(); // initializes _forV1
int GetA() const;
void SetA(int value);
float GetB() const;
void SetB(float value);
long GetC() const { return _dataV2.c } // only exists in v2
void SetC(long value) { _dataV2.c = value; } // only exists in v2
};
I would like to avoid duplicating in every getter and setter the logic that chooses the member from one version of the struct or the other. Note that while the order of members is rearranged, the types and member names are the same. I came up with this macro:
#define DATA_ACCESS(MEMBER) const_cast<decltype(_dataV1.MEMBER)&>(([&]() -> const decltype(_dataV1.MEMBER)& \
{ return (_forV1) ? _dataV1.MEMBER : _dataV2.MEMBER; })())
This allows for a somewhat elegant implementation of the property accessor functons:
int GetA() const { return DATA_ACCESS(a); }
void SetA(int value) { DATA_ACCESS(a) = value; }
float GetB() const { return DATA_ACCESS(b); }
void SetB(float value) { DATA_ACCESS(b) = value; }
I am posting this question to see if anyone has a better idea, especially an idea that doesn't involve a macro. Thanks.
With std::variant, you might do something like:
class DataWrapper // my class
{
private:
std::variant<DataV1, DataV2> data;
public:
DataWrapper(); // initializes _forV1
int GetA() const { return std::visit([](auto& arg){ return arg.a; }, data); }
void SetA(int a) const { std::visit([&a](auto& arg){ arg.a = a; }, data); }
// ...
};
I want to create a class which behaves a certain way - e.g. spits out certain values from a function double getValue(const int& x) const - based on a "type" that was passed into its constructor. Right now I have two methods:
Store the passed-in "type" and then evaluate a switch statement in getValue each time it is called in order to decide which implementation to use.
Use a switch statement on the passed-in "type" (in the constructor) to create an internal object that represents the desired implementation. So no switch required anymore in getValue itself.
Method 1 "appears" inefficient as switch is called every time I call getValue. Method 2 seems somewhat clunky as I need to utilise <memory> and it also makes copying/assigning my class non-trivial.
Are there any other cleaner methods to tackle a problem like this?
Code Example:
#include <memory>
enum class ImplType { Simple1, Simple2 /* more cases */ };
class MyClass1
{
private:
const ImplType implType;
public:
MyClass1(const ImplType& implType) : implType(implType) { }
double getValue(const int& x) const
{
switch (implType)
{
case ImplType::Simple1: return 1; /* some implemention */
case ImplType::Simple2: return 2; /* some implemention */
}
}
};
class MyClass2
{
private:
struct Impl { virtual double getValue(const int& x) const = 0; };
struct ImplSimple1 : Impl { double getValue(const int& x) const override { return 1; /* some implemention */ } };
struct ImplSimple2 : Impl { double getValue(const int& x) const override { return 2; /* some implemention */ } };
const std::unique_ptr<Impl> impl;
public:
MyClass2(const ImplType& implType) : impl(std::move(createImplPtr(implType))) { }
static std::unique_ptr<Impl> createImplPtr(const ImplType& implType)
{
switch (implType)
{
case ImplType::Simple1: return std::make_unique<ImplSimple1>();
case ImplType::Simple2: return std::make_unique<ImplSimple2>();
}
}
double getValue(const int& x) const { return impl->getValue(x); }
};
int main()
{
MyClass1 my1(ImplType::Simple1);
MyClass2 my2(ImplType::Simple1);
return 0;
}
Your code is basically mimicing a virtual method (sloppy speaking: same interface but implementation is chosen at runtime), hence your code can be much cleaner if you actually do use a virtual method:
#include <memory>
struct base {
virtual double getValue(const int& x) const = 0;
};
struct impl1 : base {
double getValue(const int& x) { return 1.0; }
};
struct impl2 : base {
double getValue(const int& x) { return 2.0; }
};
// ... maybe more...
enum select { impl1s, impl2s };
base* make_impl( select s) {
if (s == impl1s) return new impl1();
if (s == impl2s) return new impl2();
}
int main() {
std::shared_ptr<base> x{ make_impl(impl1) };
}
Not sure if this is what you are looking for. By the way, using <memory> should not make you feel "clunky", but instead you should feel proud that we have such awesome tools in c++ ;).
EDIT: If you dont want the user to work with (smart-)pointers then wrap the above in just another class:
struct foo {
shared_ptr<base> impl;
foo( select s) : impl( make_impl(s) ) {}
double getValue(const int& x) { return impl.getValue(x); }
};
now a user can do
int main() {
auto f1 { impl1s };
auto f2 { impl2s };
f1.getValue(1);
f2.getValue(2);
}
If you have a closed set of types you can choose from, you want std::variant:
using MyClass = std::variant<MyClass1, MyClass2, MyClass3, /* ... */>;
It doesn't use dynamic allocation - it's basically a type-safe modern alternative to union.
More object-oriented approach:
class Interface
{
public:
virtual int getValue() = 0;
};
class GetValueImplementation1 : public Interface
{
public:
int getValue() {return 1;}
};
class GetValueImplementation2 : public Interface
{
public:
int getValue() {return 2;}
};
class GeneralClass
{
public:
GeneralClass(Interface *interface) : interface(interface) {}
~GeneralClass()
{
if (interface)
delete interface;
}
int getValue() { return interface->getValue(); }
private:
Interface *interface;
};
So, in this case you can use it without any pointers:
int main()
{
GeneralClass obj1(new GetValueImplementation1());
GeneralClass obj2(new GetValueImplementation2());
cout << obj1.getValue() << " " << obj2.getValue();
return 0;
}
The output will be:
1 2
But in the case you should be careful with null pointers or use smart ones inside GeneralClass.
I have C library with such API:
extern "C" {
typedef struct Opaque Opaque;
Opaque *foo_new();
void foo_delete(Opaque *);
int foo_f(Opaque *, int);
}
To simplify it's usage I wrap it in such way:
class Foo final {
public:
Foo() { self_ = foo_new(); }
~Foo() { foo_delete(self_); }
//code for copy/move constructor and operator=
int f(int a) { return foo_f(self_, a); }
private:
Opaque *self_;
};
All great, but then I have to wrap array of this opaque objects:
extern "C" {
typedef struct OpaqueArray OpaqueArray;
OpaqueArray *calc_foo_array();
void foo_array_delete(OpaqueArray *);
Opaque *foo_array_elem(OpaqueArray *, size_t i);
}
So I need implement class FooArray:
class FooArray final {
public:
??? operator[](const size_t i) {
auto obj = foo_array_elem(self_, i);
???
}
private:
OpaqueArray *self_;
};
But what should I return as result of operator[]?
I can create Foo from Opaque *, but then Foo::~Foo() is free part of array,
what is wrong. I can create FooRef that would be exactly the same as Foo,
but do not call foo_delete, but actually I have several such C classes,
and I prefer do not create so many code duplicates.
May be I can somehow use reinterpret_cast, because of sizeof(Foo) = sizeof(Opaque *) and return Foo & from operator[], but Foo & actually is Opaque **,
so I need somewhere hold Opaque to make it address stable.
May be there is some standard solution for such kind of problem?
You could modify your Foo class so that it can hold a pointer that it doesn't own.
class Foo
{
public:
Foo()
{
self_ = foo_new();
m_owned = true;
}
Foo(Opaque *pOpaque)
{
self_ = foo_new();
m_owned = false;
}
~Foo()
{
if (m_owned) foo_delete(self_);
}
//code for copy/move constructor and operator=
int f(int a) { return foo_f(self_, a); }
private:
bool m_owned;
Opaque *self_;
};
class FooArray
{
public:
Foo operator[](const size_t i)
{
return Foo(foo_array_elem(self_, i));
}
private:
OpaqueArray *self_;
};
I'd do it using proposed by You FooRef but a bit differently:
class FooRef {
public:
FooRef (Opaque *o) { self_ = o; }
int f(int a) { return foo_f(self_, a); }
protected:
Opaque *self_;
};
class Foo : public FooRef {
public:
Foo() { self_ = foo_new(); }
//code for copy/move constructor and operator=
~Foo () { foo_delete(self_); }
};
This solution avoids code duplication and allows you to safely return Foo from array. And by the way you got mechanism to simply create FooRef from Foo. Now you can do just:
class FooArray final {
public:
FooRef operator[](const size_t i) {
return FooRef(foo_array_elem(self_, i));
}
private:
OpaqueArray *self_;
};
I think that this should do the trick in elegant way.
My native language is C#, so when I started using C++, I wanted to create the get/set sugar syntax for library consumers available in C#.
So I wrote...
template<typename T>
class GetProperty
{
private:
T (*get)();
public:
GetProperty(T (*get)())
{
this->get = get;
}
operator T()
{
return get();
}
template<typename S, typename T>
GetProperty<S> operator=(GetProperty<T> fool)
{
throw 0;
}
};
Then, to to use this, I wrote the code:
template<typename T>
class Vector
{
private:
struct LinkItem
{
public:
T* Item;
LinkItem* Next;
GetProperty<int> Length (&getLength);
LinkItem(T* Item = NULL, int length = 1, LinkItem* Next = NULL)
{
this->Item = Item;
this->length = length;
this->Next = Next;
}
LinkItem& operator =(LinkItem rhs)
{
this->Item = rhs.Item;
this->length = rhs.length;
this->Next = rhs.Next;
return *this;
}
private:
int length;
int getLength()
{
return length;
}
};
LinkItem* current;
.
.
.
};
However, the C/C++ addition on Netbeans (I believe this is the g++ compiler) claims I am instantiating GetProperty with no type.
According to a Google search, this happens if someone forgets a using statement, or to include a header, etc.
But int is a primitive, so this can't be.
What's going on?
You are constructing GetProperty object while declaring it in a struct. That is not allowed in C++. You have to move the construction to the constructor.
In addition to the fact that VC++ doesn't implement non-static data member initializers, you can't treat the member function getLength as an int (*)(). Its type is int (LinkItem::*)().
struct Foo {
int foo(void) {return 1;}
};
int main() {
int (*var)() = &Foo::foo; // Error
int (Foo::*var)() = &Foo::foo; // Okay
}
You probably shouldn't be trying to import a foreign idiom like this, but if you really want to you can try something like the following. (Though as Nicol Bolas points out, you also probably shouldn't be implementing your own linked list, or naming it 'vector'. If you're learning C++ just learn the C++ way before going and trying to reinvent things.)
#include <functional>
template<typename T>
class GetProperty
{
private:
std::function<int()> get;
public:
GetProperty(std::function<int()> get)
: get(get)
{}
operator T()
{
return get();
}
};
template<typename T>
class Vector
{
private:
struct LinkItem
{
public:
T* Item;
LinkItem* Next;
GetProperty<int> Length;
LinkItem(T* Item = NULL, int length = 1, LinkItem* Next = NULL)
: Length([this] { return this->getLength(); })
{
...
I realize that I'll most likely get a lot of "you shouldn't do that because..." answers and they are most welcome and I'll probably totally agree with your reasoning, but I'm curious as to whether this is possible (as I envision it).
Is it possible to define a type of dynamic/generic object in C++ where I can dynamically create properties that are stored and retrieved in a key/value type of system? Example:
MyType myObject;
std::string myStr("string1");
myObject.somethingIJustMadeUp = myStr;
Note that obviously, somethingIJustMadeUp is not actually a defined member of MyType but it would be defined dynamically. Then later I could do something like:
if(myObject.somethingIJustMadeUp != NULL);
or
if(myObject["somethingIJustMadeUp"]);
Believe me, I realize just how terrible this is, but I'm still curious as to whether it's possible and if it can be done in a way that minimizes it's terrible-ness.
C++Script is what you want!
Example:
#include <cppscript>
var script_main(var args)
{
var x = object();
x["abc"] = 10;
writeln(x["abc"]);
return 0;
}
and it's a valid C++.
You can do something very similar with std::map:
std::map<std::string, std::string> myObject;
myObject["somethingIJustMadeUp"] = myStr;
Now if you want generic value types, then you can use boost::any as:
std::map<std::string, boost::any> myObject;
myObject["somethingIJustMadeUp"] = myStr;
And you can also check if a value exists or not:
if(myObject.find ("somethingIJustMadeUp") != myObject.end())
std::cout << "Exists" << std::endl;
If you use boost::any, then you can know the actual type of value it holds, by calling .type() as:
if (myObject.find("Xyz") != myObject.end())
{
if(myObject["Xyz"].type() == typeid(std::string))
{
std::string value = boost::any_cast<std::string>(myObject["Xyz"]);
std::cout <<"Stored value is string = " << value << std::endl;
}
}
This also shows how you can use boost::any_cast to get the value stored in object of boost::any type.
This can be a solution, using RTTI polymorphism
#include <map>
#include <memory>
#include <iostream>
#include <stdexcept>
namespace dynamic
{
template<class T, class E>
T& enforce(T& z, const E& e)
{ if(!z) throw e; return z; }
template<class T, class E>
const T& enforce(const T& z, const E& e)
{ if(!z) throw e; return z; }
template<class Derived>
class interface;
class aggregate;
//polymorphic uncopyable unmovable
class property
{
public:
property() :pagg() {}
property(const property&) =delete;
property& operator=(const property&) =delete;
virtual ~property() {} //just make it polymorphic
template<class Interface>
operator Interface*() const
{
if(!pagg) return 0;
return *pagg; //let the aggregate do the magic!
}
aggregate* get_aggregate() const { return pagg; }
private:
template<class Derived>
friend class interface;
friend class aggregate;
static unsigned gen_id()
{
static unsigned x=0;
return enforce(++x,std::overflow_error("too many ids"));
}
template<class T>
static unsigned id_of()
{ static unsigned z = gen_id(); return z; }
aggregate* pagg;
};
template<class Derived>
class interface: public property
{
public:
interface() {}
virtual ~interface() {}
unsigned id() const { return property::id_of<Derived>(); }
};
//sealed movable
class aggregate
{
public:
aggregate() {}
aggregate(const aggregate&) = delete;
aggregate& operator=(const aggregate&) = delete;
aggregate(aggregate&& s) :m(std::move(s.m)) {}
aggregate& operator=(aggregate&& s)
{ if(this!=&s) { m.clear(); std::swap(m, s.m); } return *this; }
template<class Interface>
aggregate& add_interface(interface<Interface>* pi)
{
m[pi->id()] = std::unique_ptr<property>(pi);
static_cast<property*>(pi)->pagg = this;
return *this;
}
template<class Inteface>
aggregate& remove_interface()
{ m.erase[property::id_of<Inteface>()]; return *this; }
void clear() { m.clear(); }
bool empty() const { return m.empty(); }
explicit operator bool() const { return empty(); }
template<class Interface>
operator Interface*() const
{
auto i = m.find(property::id_of<Interface>());
if(i==m.end()) return nullptr;
return dynamic_cast<Interface*>(i->second.get());
}
template<class Interface>
friend aggregate& operator<<(aggregate& s, interface<Interface>* pi)
{ return s.add_interface(pi); }
private:
typedef std::map<unsigned, std::unique_ptr<property> > map_t;
map_t m;
};
}
/// this is a sample on how it can workout
class interface_A: public dynamic::interface<interface_A>
{
public:
virtual void methodA1() =0;
virtual void methodA2() =0;
};
class impl_A1: public interface_A
{
public:
impl_A1() { std::cout<<"creating impl_A1["<<this<<"]"<<std::endl; }
virtual ~impl_A1() { std::cout<<"deleting impl_A1["<<this<<"]"<<std::endl; }
virtual void methodA1() { std::cout<<"interface_A["<<this<<"]::methodA1 on impl_A1 in aggregate "<<get_aggregate()<<std::endl; }
virtual void methodA2() { std::cout<<"interface_A["<<this<<"]::methodA2 on impl_A1 in aggregate "<<get_aggregate()<<std::endl; }
};
class impl_A2: public interface_A
{
public:
impl_A2() { std::cout<<"creating impl_A2["<<this<<"]"<<std::endl; }
virtual ~impl_A2() { std::cout<<"deleting impl_A2["<<this<<"]"<<std::endl; }
virtual void methodA1() { std::cout<<"interface_A["<<this<<"]::methodA1 on impl_A2 in aggregate "<<get_aggregate()<<std::endl; }
virtual void methodA2() { std::cout<<"interface_A["<<this<<"]::methodA2 on impl_A2 in aggregate "<<get_aggregate()<<std::endl; }
};
class interface_B: public dynamic::interface<interface_B>
{
public:
virtual void methodB1() =0;
virtual void methodB2() =0;
};
class impl_B1: public interface_B
{
public:
impl_B1() { std::cout<<"creating impl_B1["<<this<<"]"<<std::endl; }
virtual ~impl_B1() { std::cout<<"deleting impl_B1["<<this<<"]"<<std::endl; }
virtual void methodB1() { std::cout<<"interface_B["<<this<<"]::methodB1 on impl_B1 in aggregate "<<get_aggregate()<<std::endl; }
virtual void methodB2() { std::cout<<"interface_B["<<this<<"]::methodB2 on impl_B1 in aggregate "<<get_aggregate()<<std::endl; }
};
class impl_B2: public interface_B
{
public:
impl_B2() { std::cout<<"creating impl_B2["<<this<<"]"<<std::endl; }
virtual ~impl_B2() { std::cout<<"deleting impl_B2["<<this<<"]"<<std::endl; }
virtual void methodB1() { std::cout<<"interface_B["<<this<<"]::methodB1 on impl_B2 in aggregate "<<get_aggregate()<<std::endl; }
virtual void methodB2() { std::cout<<"interface_B["<<this<<"]::methodB2 on impl_B2 in aggregate "<<get_aggregate()<<std::endl; }
};
int main()
{
dynamic::aggregate agg1;
agg1 << new impl_A1 << new impl_B1;
dynamic::aggregate agg2;
agg2 << new impl_A2 << new impl_B2;
interface_A* pa = 0;
interface_B* pb = 0;
pa = agg1; if(pa) { pa->methodA1(); pa->methodA2(); }
pb = *pa; if(pb) { pb->methodB1(); pb->methodB2(); }
pa = agg2; if(pa) { pa->methodA1(); pa->methodA2(); }
pb = *pa; if(pb) { pb->methodB1(); pb->methodB2(); }
agg2 = std::move(agg1);
pa = agg2; if(pa) { pa->methodA1(); pa->methodA2(); }
pb = *pa; if(pb) { pb->methodB1(); pb->methodB2(); }
return 0;
}
tested with MINGW4.6 on WinXPsp3
Yes it is terrible. :D
It had been done numerous times to different extents and success levels.
QT has Qobject from which everything related to them decends.
MFC has CObject from which eveything decends as does C++.net
I don't know if there is a way to make it less bad, I guess if you avoid multiple inheritance like the plague (which is otherwise a useful language feature) and reimplement the stdlib it would be better. But really if that is what you are after you are probably using the wrong language for the task.
Java and C# are much better suited to this style of programming.
#note if I have read your question wrong just delete this answer.
Check out Dynamic C++