Commit 5a99b769 authored by Kirill Smelkov's avatar Kirill Smelkov

libgolang: Start providing interfaces

- interface is analog of interface{} in Go.
- error is analog of error in Go.

For now the interfaces are implemented via classic C++ scheme via
inheritance and additional vtable field in pointed object.

In the future we might want to consider reworking that to Go-style
interfaces without predeclaring which interfaces a class implements.

Top-level documentation is TODO.

Interfaces will be soon needed to describe Context interface in C
context package.
parent 274afa3f
...@@ -46,6 +46,7 @@ In addition to Cython/nogil API, golang.pyx provides runtime for golang.py: ...@@ -46,6 +46,7 @@ In addition to Cython/nogil API, golang.pyx provides runtime for golang.py:
from libcpp cimport nullptr_t, nullptr as nil from libcpp cimport nullptr_t, nullptr as nil
from libcpp.utility cimport pair from libcpp.utility cimport pair
from libcpp.string cimport string
from libc.stdint cimport uint64_t from libc.stdint cimport uint64_t
cdef extern from *: cdef extern from *:
ctypedef bint cbool "bool" ctypedef bint cbool "bool"
...@@ -151,6 +152,27 @@ cdef extern from "golang/libgolang.h" namespace "golang" nogil: ...@@ -151,6 +152,27 @@ cdef extern from "golang/libgolang.h" namespace "golang" nogil:
void incref() void incref()
int refcnt() const int refcnt() const
# empty interface ~ interface{}
cppclass _interface:
void incref()
void decref()
cppclass interface (refptr[_interface]):
# interface.X = interface->X in C++
void incref "_ptr()->incref" ()
void decref "_ptr()->decref" ()
# error interface
cppclass _error (_interface):
string Error()
cppclass error (refptr[_error]):
# error.X = error->X in C++
string Error "_ptr()->Error" ()
# ---- python bits ---- # ---- python bits ----
cdef void topyexc() except * cdef void topyexc() except *
......
...@@ -475,6 +475,8 @@ template<typename T> refptr<T> newref (T *_obj); ...@@ -475,6 +475,8 @@ template<typename T> refptr<T> newref (T *_obj);
// //
// T must provide incref/decref methods for example via inheriting from object. // T must provide incref/decref methods for example via inheriting from object.
// incref/decref must be safe to use from multiple threads simultaneously. // incref/decref must be safe to use from multiple threads simultaneously.
//
// See also interface.
template<typename T> template<typename T>
class refptr { class refptr {
T *_obj; T *_obj;
...@@ -606,6 +608,28 @@ public: ...@@ -606,6 +608,28 @@ public:
LIBGOLANG_API int refcnt() const; LIBGOLANG_API int refcnt() const;
}; };
// interface is empty interface a-la interface{} in Go.
//
// It is the base class of all interfaces.
//
// Even if the interface is empty, it requires memory-management methods to be
// present. See refptr for details.
struct _interface {
virtual void incref() = 0;
virtual void decref() = 0;
protected:
// don't use destructor -> use decref
~_interface();
};
typedef refptr<_interface> interface;
// error is the interface describing errors.
struct _error : _interface {
virtual std::string Error() = 0;
};
typedef refptr<_error> error;
} // golang:: } // golang::
......
...@@ -1199,6 +1199,8 @@ void _blockforever() { ...@@ -1199,6 +1199,8 @@ void _blockforever() {
bug("_blockforever: woken up"); bug("_blockforever: woken up");
} }
_interface::~_interface() {}
// ---- for tests ---- // ---- for tests ----
// _tchanlenrecvqlen returns len(_ch._recvq) // _tchanlenrecvqlen returns len(_ch._recvq)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment