Why doesn't is() -- the boost state machine API -- recognize a struct? - c++

We use boost sml library to implement a state machine in our production system. There is a thread that sends various events into the state machine for processing. From another thread, I need to read the current state. I cannot get a piece of code using boost sml's is() API to compile! It gives me some weird errors:
nm_state_machine->is(ConnectExternalNode{});
error: no type named ‘type’ in ‘struct ConnectExternalNode’
return aux::get_id<state_t, typename TState::type>((states_ids_t *)0)
== aux::cget<sm_impl_t>(sub_sms_).current_state_[0];
All the boost sml examples in the official docs show states as string and events as struct. We use struct for both states and events. For example, the state for the above code is this:
struct ConnectExternalNode {};
My questions are:
Why isn't the is() method taking a struct instance even though it is a valid type for a state?
Is the is() method thread-safe?

Related

C++ static reflection TS: would it support assign/call by name?

There is a C++ Technical Specification on static reflection (current PDF draft and cppreference page)
which might move into C++23 or later.
Would it be possible in the current draft (I understand syntax is perhaps not fixed yet)
to access struct fields / call class member functions by name?
For instance
struct Test {
int x;
int y;
};
Test foo;
auto meta = reflexpr(foo); // access meta information about class
some_magic_setter<"x", meta>(foo, 5); // ??? Should do: `foo.x = 5`
Would this be possible and if yes how ?
EDIT: When I look into the TS draft I find most of the functions are named 'get_XX' (like get_type, get_scope, ...) or 'is_XXX' (like is_private, ...) which seems to to only give information (which is obvoiously the purpose of reflection). However, I cannot find anything that seems to allow member access of a given object. Any hints are welcome.
get_pointer<X> gets you a pointer to member, get_name<X> gets its name. Throw in some iterating over members (also supplied), and handling of type mismatching (which could be done in c++03), and bob is your uncle.
C++ gives compile time reflection primitives; so you have to write the glue code yourself as far as I am aware.
I would start with a function making a tuple of (name member pointer) pairs using reflection. It can be pure constexpr.
Then another function that does setting based on that structure, where runtime failure is in play.
That will let you unit test both pieces seperately; only the building of the "dictionary" requires reflection.

How to store enumerate types/store type info across modules in C++

I'm working on a game engine incorporating ECS. I have a pretty straightforward setup - my engine is in a DLL and my game module is the .EXE which attaches the DLL. I have created an ECS using dense memory block allocations and I'm focusing quite a lot on performance. For the very basis of the ECS i use a type info structure to enumerate different entity component types. I basically use function pointers to templated functions as a way to enumerate different types. It is defined as follows:
struct ComponentTypeInfo
{
typedef (*_InternalId)();
_InternalId TypeId;
size_t TypeSize;
protected:
template<typename>
static void TypeId() {}
}
template<typename TComponent>
struct GetComponentTypeInfo : public ComponentTypeInfo
{
GetComponentTypeInfo() : ComponentTypeInfo(TypeId<TComponent>, sizeof(TComponent))
}
The problem: In practice this works fine, however it breaks when types are compared across modules due to function instances being seperate. This causes the the function pointers to be different, and therefore the Ids to be different. I have tried a bunch of things but they all come to the same issue regarding module boundries.
What I have thought of so far:
Making sure only one module uses type info - Practically impossible since the engine has own component types predefined to use in systems.
Using a counter/increment-style id - Still encounters the same problem - any way of attaching ids to types encounters the problem that templated functionality is always instantiated in its own module, thus the ids would never match.
Using inheritence - since the ECS uses densely packed memory blocks, type erasure happens very early on and the logic working with memory blocks and stacks doesnt have the compile-time information of the types stored. Just the type ids.
I want to stay away from STL unless I absolutely need to use it. However I might end up using a wrapper around it if nothing else works. Libraries (boost, etc) are not a consideration.
Is there any senseble way to enumerate types across modules? Is RTTI only made to be available to STL?

SCIP: About the "SCIP_ReaderData" in the bin packing example

A quesion about the reader plugin defined in the binpacking example. I found the following declaration in the interface method (file reader_bpa.c),
SCIP_READERDATA* readerdata;
readerdata = NULL;
I know SCIP_READERDATA is defined in file type_reader.h:
typedef struct SCIP_ReaderData SCIP_READERDATA;
However, the struct SCIP_ReaderData is not defined in the binpacking reader, so which is the actual struct that "SCIP_READERDATA* readerdata;" reference to? what kind of pointer is readerdata?
PS: I noticed that the default readers in SCIP have similar usage.
That is more a C-question than a SCIP question if I am not mistaken. The interface functions SCIPincludeReader() and SCIPincludeReaderBasic() require a pointer to reader data as last argument. Reader data is supposed to allow the plugin author to connect arbitrary data with their reader plugin by declaring the corresponding struct SCIP_ReaderData as many other plugins do.
If you try to do anything with the pointer, e.g., allocate memory for it using SCIPallocMemory(scip, &readerdata), you will get compiler errors because the pointer refers to an incomplete type, namely struct SCIP_ReaderData.
More useful information on incomplete types is found, e.g., here
The point is, the example uses this to make it clearer which arguments are passed to the SCIPIncludeReaderBasic()-function, where you would see NULL otherwise.

Serializing function objects

Is it possible to serialize and deserialize a std::function, a function object, or a closure in general in C++? How? Does C++11 facilitate this? Is there any library support available for such a task (e.g., in Boost)?
For example, suppose a C++ program has a std::function which is needed to be communicated (say via a TCP/IP socket) to another C++ program residing on another machine. What do you suggest in such a scenario?
Edit:
To clarify, the functions which are to be moved are supposed to be pure and side-effect-free. So I do not have security or state-mismatch problems.
A solution to the problem is to build a small embedded domain specific language and serialize its abstract syntax tree.
I was hoping that I could find some language/library support for moving a machine-independent representation of functions instead.
Yes for function pointers and closures. Not for std::function.
A function pointer is the simplest — it is just a pointer like any other so you can just read it as bytes:
template <typename _Res, typename... _Args>
std::string serialize(_Res (*fn_ptr)(_Args...)) {
return std::string(reinterpret_cast<const char*>(&fn_ptr), sizeof(fn_ptr));
}
template <typename _Res, typename... _Args>
_Res (*deserialize(std::string str))(_Args...) {
return *reinterpret_cast<_Res (**)(_Args...)>(const_cast<char*>(str.c_str()));
}
But I was surprised to find that even without recompilation the address of a function will change on every invocation of the program. Not very useful if you want to transmit the address. This is due to ASLR, which you can turn off on Linux by starting your_program with setarch $(uname -m) -LR your_program.
Now you can send the function pointer to a different machine running the same program, and call it! (This does not involve transmitting executable code. But unless you are generating executable code at run-time, I don't think you are looking for that.)
A lambda function is quite different.
std::function<int(int)> addN(int N) {
auto f = [=](int x){ return x + N; };
return f;
}
The value of f will be the captured int N. Its representation in memory is the same as an int! The compiler generates an unnamed class for the lambda, of which f is an instance. This class has operator() overloaded with our code.
The class being unnamed presents a problem for serialization. It also presents a problem for returning lambda functions from functions. The latter problem is solved by std::function.
std::function as far as I understand is implemented by creating a templated wrapper class which effectively holds a reference to the unnamed class behind the lambda function through the template type parameter. (This is _Function_handler in functional.) std::function takes a function pointer to a static method (_M_invoke) of this wrapper class and stores that plus the closure value.
Unfortunately, everything is buried in private members and the size of the closure value is not stored. (It does not need to, because the lambda function knows its size.)
So std::function does not lend itself to serialization, but works well as a blueprint. I followed what it does, simplified it a lot (I only wanted to serialize lambdas, not the myriad other callable things), saved the size of the closure value in a size_t, and added methods for (de)serialization. It works!
No.
C++ has no built-in support for serialization and was never conceived with the idea of transmitting code from one process to another, lest one machine to another. Languages that may do so generally feature both an IR (intermediate representation of the code that is machine independent) and reflection.
So you are left with writing yourself a protocol for transmitting the actions you want, and the DSL approach is certainly workable... depending on the variety of tasks you wish to perform and the need for performance.
Another solution would be to go with an existing language. For example the Redis NoSQL database embeds a LUA engine and may execute LUA scripts, you could do the same and transmit LUA scripts on the network.
No, but there are some restricted solutions.
The most you can hope for is to register functions in some sort of global map (e.g. with key strings) that is common to the sending code and the receiving code (either in different computers or before and after serialization).
You can then serialize the string associated with the function and get it on the other side.
As a concrete example the library HPX implements something like this, in something called HPX_ACTION.
This requires a lot of protocol and it is fragile with respect to changes in code.
But after all this is no different from something that tries to serialize a class with private data. In some sense the code of the function is its private part (the arguments and return interface is the public part).
What leaves you a slip of hope is that depending on how you organize the code these "objects" can be global or common and if all goes right they are available during serialization and deserialization through some kind predefined runtime indirection.
This is a crude example:
serializer code:
// common:
class C{
double d;
public:
C(double d) : d(d){}
operator(double x) const{return d*x;}
};
C c1{1.};
C c2{2.};
std::map<std::string, C*> const m{{"c1", &c1}, {"c2", &c2}};
// :common
main(int argc, char** argv){
C* f = (argc == 2)?&c1:&c2;
(*f)(5.); // print 5 or 10 depending on the runtime args
serialize(f); // somehow write "c1" or "c2" to a file
}
deserializer code:
// common:
class C{
double d;
public:
operator(double x){return d*x;}
};
C c1;
C c2;
std::map<std::string, C*> const m{{"c1", &c1}, {"c2", &c2}};
// :common
main(){
C* f;
deserialize(f); // somehow read "c1" or "c2" and assign the pointer from the translation "map"
(*f)(3.); // print 3 or 6 depending on the code of the **other** run
}
(code not tested).
Note that this forces a lot of common and consistent code, but depending on the environment you might be able to guarantee this.
The slightest change in the code can produce a hard to detect logical bug.
Also, I played here with global objects (which can be used on free functions) but the same can be done with scoped objects, what becomes trickier is how to establish the map locally (#include common code inside a local scope?)

How to perform type scanning in C++?

I have an ESB. Any serialized message transports its own fully qualified name (that is, namespace + class name). I have a concrete type for each message that encapsulates a specific logic to be executed.
Every time I receive a message, I need to deserialize it at first, so I can perform its operations --once more, depending on its concrete type--.
I need a way to register every single class at compile time or during my application initialization.
With .net I would use reflection to scan assemblies and discover the message types during initialization, but how would you do it in C++?
C++ has no reflection capability. I suppose you could try to scan object files, etc., but there's no reliable way to do this (AFAIK); the compiler may entirely eliminate or mangle certain things.
Essentially, for serialization, you will have to do the registration (semi-)manually. But you may be interested in a serialization library that will help out with the chores, such as Boost Serialization.
Since there is no reflection in C++, I would suggest using an external script to scan your source code for all relevant classes (which is easy if you use empty dummy #defines to annotate them in the source code) and have it generate the registration code.
I personally use the manual registration road. If you forget to register... then the test don't work anyway.
You just have to use a factory, and implement some tag dispatching. For example:
typedef void (*ActOnMessageType)(Message const&);
typedef std::map<std::string, ActOnMessageType> MessageDispatcherType;
static MessageDispatcherType& GetDispatcher() {
static MessageDispatcherType D; return D;
}
static bool RegisterMessageHandler(std::string name, ActOnMessageType func) {
return GetDispatcher().insert(std::make_pair(name, func)).second;
}
Then you just prepare your functions:
void ActOnFoo(Message const& m);
void ActOnBar(Message const& m);
And register them:
bool const gRegisteredFoo = RegisterMessageHandler("Foo", ActOnFoo);
bool const gRegisteredBar = RegsiterMessageHandler("Bar", ActOnBar);
Note: I effectively use a lazily initialized Singleton, in order to allow decoupling. That is the registration is done during the library load and thus each Register... call is placed in the file where the function is defined. The one difference with a global variable is that here the dispatching map is actually constant once the initialization ends.