#ifndef Arguments_h
#define Arguments_h
#include "ArgumentDecoder.h"
#include "ArgumentEncoder.h"
namespace IPC {
template<size_t index, typename... Elements>
struct TupleCoder {
static void encode(ArgumentEncoder& encoder, const std::tuple<Elements...>& tuple)
{
encoder << std::get<sizeof...(Elements) - index>(tuple);
TupleCoder<index - 1, Elements...>::encode(encoder, tuple);
}
static bool decode(ArgumentDecoder& decoder, std::tuple<Elements...>& tuple)
{
if (!decoder.decode(std::get<sizeof...(Elements) - index>(tuple)))
return false;
return TupleCoder<index - 1, Elements...>::decode(decoder, tuple);
}
};
template<typename... Elements>
struct TupleCoder<0, Elements...> {
static void encode(ArgumentEncoder&, const std::tuple<Elements...>&)
{
}
static bool decode(ArgumentDecoder&, std::tuple<Elements...>&)
{
return true;
}
};
template<typename... Elements> struct ArgumentCoder<std::tuple<Elements...>> {
static void encode(ArgumentEncoder& encoder, const std::tuple<Elements...>& tuple)
{
TupleCoder<sizeof...(Elements), Elements...>::encode(encoder, tuple);
}
static bool decode(ArgumentDecoder& decoder, std::tuple<Elements...>& tuple)
{
return TupleCoder<sizeof...(Elements), Elements...>::decode(decoder, tuple);
}
};
template<typename... Types>
struct Arguments {
typedef std::tuple<typename std::decay<Types>::type...> ValueType;
Arguments(Types&&... values)
: arguments(std::forward<Types>(values)...)
{
}
void encode(ArgumentEncoder& encoder) const
{
ArgumentCoder<std::tuple<Types...>>::encode(encoder, arguments);
}
static bool decode(ArgumentDecoder& decoder, Arguments& result)
{
return ArgumentCoder<std::tuple<Types...>>::decode(decoder, result.arguments);
}
std::tuple<Types...> arguments;
};
}
#endif // Arguments_h