[WIP] [Discussion?] C++ Bindings #123
[WIP] [Discussion?] C++ Bindings #123
Conversation
include/libtransistor/cpp/types.hpp
Outdated
|
||
namespace Transistor { | ||
|
||
struct Unit {}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does something like this already exist in STL?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
http://en.cppreference.com/w/cpp/utility/variant/monostate
not sure if it's standard practice to actually use it independently of std::variant though
lib/cpp/ipc/hid.cpp
Outdated
return ResultCode::Maybe(hid_ipc_get_shared_memory_handle(&handle)).rightMap([&handle](auto const &v) -> std::shared_ptr<KSharedMemory> { | ||
return std::make_shared<KSharedMemory>(handle); | ||
}); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't like using shared_ptr
here, since I think that using such a thing is a decision that the caller should be able to make, but I also couldn't find a way to get the KSharedMemory
object out without it or a copy of it getting destructed and closing the handle, which raises the question of how a KObject
should behave when it is copied. Should it increase some reference count for the object? At that point, you may as well use std::shared_ptr
, which is the solution I chose. Can we explicitly disable copying and force it to always be moved? I have a lot to learn about such memory management in modern C++. I keep trying to apply the concepts I picked up from Rust to C++ but don't know how.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it is possible to disable copy constructors if you want it to behave like a singleton that can only be moved.
What do we want our C++ API to look like? I've written a little bit, but I'd love to hear some opinions, especially from some people more familiar wtih C++ than I am.
Monadic Error Handling:
This is one of the things I've been most excited about with C++ bindings, but the way I have it is really verbose. I'm not really sure I like
neither
, too, and it doesn't look like we havestd::expected
yet.One of the things I found myself missing most from Rust was the
try!
macro, which we might be able to implement using a preprocessor macro? I'd appreciate it if somebody found better way of doing this.Module Initialization:
I wanted to be able to handle this RAII style, which I think turned out decently. In order to interact with a module, you need to get an object for it. You can either copy one from someone else (in which case it should already be initialized, so we just
AssertOk
the_init()
function), or callModule::Initialize()
, which can handle the error case.Code Style:
When I'm writing C, I prefer using underscores_and_all_lowercase. When it comes to C++ though, I'm somewhat less opinionated. My natural inclination is to use CamelCase in languages like C++, and I kinda like that that provides a sort of distinction between the C++ API and the C API. There's a lot of little things we might want to nail down in C++ style, too. Should member names start with a capital letter? How should
public
,private
, andprotected
be indented?Another thing I want to make sure we keep in mind is to make sure that our code stays readable, especially if we start using a lot of templates. I like my header files to be clean and concise, and templates have a tendency to fill up the header file with a lot of code that's hard to read, hard to understand, and takes up a lot of space.
Build System:
I think I want to move the C++ bindings into an entirely different directory from the C libtransistor, and build them into a separate archive. This means we can separate the dependencies for the C libtransistor and the C++ bindings.
Other Things:
We're going to have to put
extern "C"
guards around all our header files. I really hate that this is a thing we have to do, since it's just meaningless noise in our header files taking up space that we have to put there to please the overly pedantic compiler that probably already knows what we mean, but we're going to have to anyway.