How to get named list of arguments from fmt::format_args - fmt

I'm trying to build C++ logging integration for Logz.IO which uses named parameters for string interpolation and I'd like to leverage fmt for argument parsing and formatting. Essentially I'm trying to build function that will allow me to pass named arguments e.g.
log_fmt("Length: {Length:.2f}", fmt::arg("Length", 125.5f));
I followed documentation to build templated function and my own logging function:
template <typename S, typename... Args>
void log_fmt(const S& format, Args&&... args) {
vlog(level, format,
fmt::make_args_checked<Args...>(format, args...));
}
void vlog(fmt::string_view format, fmt::format_args args) {}
Inside my implementation of vlog I would like to convert args to JSON object that will contain all arguments (ideally without formatting part):
{
"Length": 125.5
}
However it looks like format_args exposes only very basic public interface (only allowing to get. How can I iterate over args and get each argument name and value?

{fmt} doesn't provide an API to iterate over named arguments but you can do it yourself in log_fmt. Each named argument will have the following type:
template <typename Char, typename T> struct named_arg : view {
const Char* name;
const T& value;
named_arg(const Char* n, const T& v) : name(n), value(v) {}
};

Related

Const struct in D

I am trying to pass a struct as a compile time argument to a function.
I think the code is self explanatory. I am fairly certain that this should work. But I don't know why it won't work.
void main(string[] args)
{
const FooStruct fooStruct = FooStruct(5);
barFunction!fooStruct();
}
public struct FooStruct()
{
private const int value_;
#property int value() { return value_; }
this(int value) const
{
value_ = value;
}
}
public static void barFunction(FooStruct fooStruct)
{
fooStruct.value; /// do something with it.
}
public struct FooStruct()
Here, you're declaring FooStruct to be a templated struct, with no variables. If that's what you want, you'll need to refer to FooStruct!() on this line:
public static void barFunction(FooStruct fooStruct)
Since FooStruct takes no template arguments, there's not really any need for it to be templated, and you should probably declare it like this:
public struct FooStruct
When you do that, the error message changes to constructor FooStruct.this (int value) const is not callable using argument types (int). That's because you're invoking the mutable constructor. To fix that, change line 3 to read const FooStruct fooStruct =constFooStruct(5);.
Finally, when you call barFunction, you are attempting to pass fooStruct as a template parameter (barFunction!fooStruct()). Since barFunction is not a templated function, this fails. You probably meant barFunction(fooStruct).

C++11 thread pool - tasks with input parameters

I am trying to use a simple thread pool example from the book of Anthony Williams "C++ Concurrency in Action". I have even found the code here (the class thread_pool) in one of the posts:
Synchronizing tasks
but I have a different question. I would like to submit a task (a member function) to the queue with the following signature:
class A;
class B;
bool MyClass::Func(A*, B*);
How would I need to change the thread_pool class, or how do I pack my function in some void F(), which is assumed to be used as a task in this example?
Here is the most relevant part of the class for me (for the details please see the link above):
class thread_pool
{
thread_safe_queue<std::function<void()> work_queue; // bool MyClass::Func(a,b) ??
void worker_thread() {
while(!done) {
std::function<void()> task;
if(work_queue.try_pop(task)) {
task(); // how should my function MyClass::Func(a,b) be called here?
}
else {
std::this_thread::yield();
}
}
}
// -- Submit a task to the thread pool
template <typename FunctionType>
void submit(FunctionType f) {
work_queue.push(std::function<void()>(f)); // how should bool MyClassFunc(A*, B*) be submitted here
}
}
And finally, how can I call the submit Function in my code?
Thank you very much for your help (unfortunatelly I am not very experienced yet in using all the C++11 features, which is probably also why I need help here, but an answer to this question would be something to start with :)).
You have to bind the parameters to a value when you insert a task into the queue. That means that you have to create a wrapper for your function that stores the values for this and the values for the two function parameters. There are many ways to do this, e.g. lambda functions or std::bind.
work_queue.push_back( [obj, a, b]() {obj->Func(a,b)} );
work_queue.push_back( std::bind(&MyClass::Func, obj, a, b) );
Your submit function must take these parameters and create the binding, e.g.
template<typename F, typename... Args>
void submit(F f, Args&&... args) {
work_queue.push_back( std::bind(f, std::forward<Args>(args)...) );
}
It may be convenient to create a special overload for member functions and objects.
I've written something that does something (very) similar to this before. I'll post the code here and you can have a look. GenCmd is the function wrapper. The queue looks like this, and is used/defined in Impl (code omitted). You only need to look at implementation of GenCmd, as this contains the necessary work.
ConcurrentQueue<std::unique_ptr<Cmd>> cqueue_;
I've wrapped std::function<> to be polymorphic in queue. std_utility contains make_index_sequence, that is used to extract values from a tuple (google make_index_sequence to find an implementation somewhere if this is not already part of your std library).
#include <functional>
#include <memory>
#include <iostream>
#include <utility>
#include <boost/noncopyable.hpp>
class CmdExecutor : public boost::noncopyable
{
public:
CmdExecutor(std::ostream& errorOutputStream);
~CmdExecutor();
template <class Receiver, class ... FArgs, class ... CArgs >
void process(Receiver& receiver, void (Receiver::*f)(FArgs...), CArgs&&... args)
{
process(std::unique_ptr<Cmd>(new GenCmd<void(Receiver,FArgs...)>(f, receiver, std::forward<CArgs>(args)...)));
}
private:
class Cmd
{
public:
virtual void execute() = 0;
virtual ~Cmd(){}
};
template <class T> class GenCmd;
template <class Receiver, class ... Args>
class GenCmd<void(Receiver, Args...)> : public Cmd
{
public:
template <class FuncT, class ... CArgs>
GenCmd(FuncT&& f, Receiver& receiver, CArgs&&... args)
: call_(std::move(f)),
receiver_(receiver),
args_(args...)
{
}
//We must convert references to values...
virtual void execute()
{
executeImpl(std::make_index_sequence<sizeof...(Args)>{});
}
private:
template <std::size_t ... Is>
void executeImpl(std::index_sequence<Is...>)
{
// We cast the values in the tuple to the original type (of Args...)
call_(receiver_, static_cast<Args>(std::get<Is>(args_))...);
}
std::function<void(Receiver&, Args...)> call_;
Receiver& receiver_;
// NOTE:
// References converted to values for safety sake, as they are likely
// to not be around when this is executed in other context.
std::tuple<typename std::remove_reference<Args>::type...> args_;
};
void process(std::unique_ptr<Cmd> command);
class Impl;
Impl* pimpl_;
};
It's basically used as follows:
...
CmdExecutor context_;
...
void MyClass::myFunction()
{
ArgX x;
ArgY y;
context_.process(*this, &MyClass::someFunction, x, y);
}
You can see from this that process does the wrapping of member function type and converts it to the underlying type for storage on queue. This allows for multiple argument types. I've opted for using runtime polymorphism to store the function types, hence the GenCmd derivative.
Note: If the invoked function receives an rvalue (Arg&&), the stored type is casted to the original type, therefore causing a move, and rendering the applicable command argument (which would only be invoked once) empty (that's the intent, at least - untested...)

In Haxe, how do you pass Enum values in functions, and then convert them to Strings within the function?

I can't seem to get this working, but I'd be surprised if it wasn't possible in Haxe.
I'm trying to pass a couple of Enum values defined in my game to a function, so that it can then concatenate them as String types and pass that to other functions.
Example:
// In a general Entity class:
public override function kill():Void {
messages.dispatchCombined(entityType, ListMessages.KILLED);
super.kill();
}
And in my Messages.hx class:
package common;
import msignal.Signal.Signal1;
/**
* A Message / Event class using Signals bound to String names.
* #author Pierre Chamberlain
*/
class Messages{
var _messages:MessagesDef;
public function new() {
_messages = new MessagesDef();
}
public function add(pType:String, pCallback:FuncDef) {
if (_messages[pType] == null) {
_messages[pType] = new Signal1<Dynamic>();
}
var signals = _messages[pType];
signals.add( pCallback );
}
public function dispatch(pType:String, pArg:Dynamic):Bool {
var signals = _messages[pType];
if (signals == null) return false;
signals.dispatch(pArg);
return true;
}
//Compiler doesn't like passing enums :(
public inline function addCombined(pSource:Enum, pEvent:Enum, pCallback:FuncDef) {
add( combine(pSource, pEvent), pCallback );
}
public inline function dispatchCombined(pSource:Enum, pEvent:Enum, pArg:Dynamic):Bool {
return dispatch( combine(pSource, pEvent), pArg);
}
//How can I just pass the enum "names" as strings?
static inline function combine(a:Enum, b:Enum):String {
return String(a) + ":" + String(b);
}
}
typedef MessagesDef = Map<String, Signal1<Dynamic>>;
typedef FuncDef = Dynamic->Void;
Note how addCombined, dispatchCombined and combine expect an "Enum" type, but in this case I'm not sure if Haxe actually expects the entire Enum "class" to be passed (ie: ListMessages instead of ListMessages.KILLED) or if a value should work. Anyways, compiler doesn't like it - so I'm assuming another special Type has to be used.
Is there another way to go about passing enums and resolving them to strings?
I think you need EnumValue as parameter type (if it is only for enum values), and use Std.String to convert to String values.
static inline function combine(a:EnumValue, b:EnumValue):String {
return Std.string(a) + ":" + Std.string(b);
}
Of course that can be written smaller using String interpolation:
static inline function combine(a:EnumValue, b:EnumValue):String {
return '$a:$b';
}
Of course that can be 'more dynamic' using type parameters:
static inline function combine<A, B>(a:A, b:B):String {
return '$a:$b';
}
There is totally no need to use Dynamic as suggested. If you use Dynamic, you basically turn off the type system.
live example:
http://try.haxe.org/#a8844
Use Dynamic instead of Enum or pass them as Strings right away since you can always convert to enum from String if you need it later.
Anyway pass the enum as enum:Dynamic and then call Std.string(enum);
EDIT: Using EnumValue is definitely better approach than Dynamic, I use Dynamic in these functions because I send more than just Enums there and I am not worried about type safety in that case.

QtConcurrent::map() with member function = can not compile

My project is to create a small program which demonstrates the work of a search engine: indexing and returning result for arbitrary queries. I've done the work with the indexer part and now I want to improve it with indexing multiple files at once. The MainWindow class is here:
class MainWindow : public QMainWindow
{
Q_OBJECT
.....
private:
Indexer * indexer;
QStringList fileList;
....
void index(QStringList list);
void add(const QString &filename);
}
This is the implementation of add (add need to access fileList to avoid index the same files again, thus it can not be static method):
void MainWindow::add(const QString &filename)
{
if (!fileList.contains(filename))
{
indexer->addDocument(filename.toStdString());
fileList.append(filename);
qDebug() << "Indexed" << filename;
emit updatedList(fileList);
}
}
The implement of index method is to receive a file lists and call add upon each file name:
void MainWindow::index(QStringList list)
{
....
QtConcurrent::map(list, &MainWindow::add);
....
}
The error I receive when compiling these code is:
usr/include/qt4/QtCore/qtconcurrentmapkernel.h: In member function 'bool QtConcurrent::MapKernel<Iterator, MapFunctor>::runIteration(Iterator, int, void*) [with Iterator = QList<QString>::iterator, MapFunctor = QtConcurrent::MemberFunctionWrapper1<void, MainWindow, const QString&>]':
../search-engine/mainwindow.cpp:361:1: instantiated from here
/usr/include/qt4/QtCore/qtconcurrentmapkernel.h:73:9: error: no match for call to '(QtConcurrent::MemberFunctionWrapper1<void, MainWindow, const QString&>) (QString&)'
/usr/include/qt4/QtCore/qtconcurrentfunctionwrappers.h:128:7: note: candidate is:
/usr/include/qt4/QtCore/qtconcurrentfunctionwrappers.h:138:14: note: T QtConcurrent::MemberFunctionWrapper1<T, C, U>::operator()(C&, U) [with T = void, C = MainWindow, U = const QString&]
/usr/include/qt4/QtCore/qtconcurrentfunctionwrappers.h:138:14: note: candidate expects 2 arguments, 1 provided
I'm not really familiar with how QtConcurrent works, and the documentation doesn't provide much details about it. I really hope that someone here can help. Thanks in advance.
To be able to call a pointer-to-member, you need, in addition to that functions formal arguments, an instance of that class (the this pointer that you get inside member functions).
There are two ways to handle this: create a simple functor to wrap the call, or use a lambda.
The functor would look like this:
struct AddWrapper {
MainWindow *instance;
AddWrapper(MainWindow *w): instance(w) {}
void operator()(QString const& data) {
instance->add(data);
}
};
And you'd use it like:
AddWrapper wrap(this);
QtConcurrent::map(list, wrap);
(Careful with the lifetime of that wrapper though. You could make that more generic - you could also store a pointer-to-member in the wrapper for instance, and/or make it a template if you want to reuse that structure for other types.)
If you have a C++11 compiler with lambdas, you can avoid all that boilerpalte:
QtConcurrent::map(list, [this] (QString const& data) { add(data); });
Note: I'm not sure how QtConcurrent::MemberFunctionWrapper1 got involved in your example, I'm not seeing it here. So there might be a generic wrapper already in Qt for this situation, but I'm not aware of it.

C# Func(T) not accepting ref type input parameter

Can Func<...> accept arguments passed by reference in C#?
static void Main()
{
Func<string,int, int> method = Work;
method.BeginInvoke("test",0, Done, method);
// ...
//
}
static int Work(ref string s,int a) { return s.Length; }
static void Done(IAsyncResult cookie)
{
var target = (Func<string, int>)cookie.AsyncState;
int result = target.EndInvoke(cookie);
Console.WriteLine("String length is: " + result);
}
I am not able define a Func<...> which can accept the ref input parameter.
The Func<T> delegates cannot take ref parameters.
You need to create your own delegate type which takes ref parameters.
However, you shouldn't be using ref here in the first place.
Expanding on SLaks answers.
The Func<T> family of delegates are generic and allow you to customize the type of the arguments and returns. While ref contributes to C#`s type system it's not actually a type at the CLR level: it's a storage location modifier. Hence it's not possible to use a generic instantiation to control whether or not a particular location is ref or not.
If this was possible it would be very easy to produce completely invalid code. Consider the following
T Method<T>() {
T local = ...;
...
return local;
}
Now consider what happens if the developer called Method<ref int>(). It would produce both a local and return value which are ref. This would result in invalid C# code.

Resources