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
from libcpp cimport nullptr_t, nullptr as nil
from libcpp.utility cimport pair
from libcpp.string cimport string
from libc.stdint cimport uint64_t
cdef extern from *:
ctypedef bint cbool "bool"
......@@ -151,6 +152,27 @@ cdef extern from "golang/libgolang.h" namespace "golang" nogil:
void incref()
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 ----
cdef void topyexc() except *
......@@ -475,6 +475,8 @@ template<typename T> refptr<T> newref (T *_obj);
// T must provide incref/decref methods for example via inheriting from object.
// incref/decref must be safe to use from multiple threads simultaneously.
// See also interface.
template<typename T>
class refptr {
T *_obj;
......@@ -606,6 +608,28 @@ public:
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;
// don't use destructor -> use decref
typedef refptr<_interface> interface;
// error is the interface describing errors.
struct _error : _interface {
virtual std::string Error() = 0;
typedef refptr<_error> error;
} // golang::
......@@ -1199,6 +1199,8 @@ void _blockforever() {
bug("_blockforever: woken up");
_interface::~_interface() {}
// ---- for tests ----
// _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