mirror of
https://github.com/pocoproject/poco.git
synced 2025-03-29 02:45:21 +01:00
Added support for std::tuple to Data/Typehandler.h.
This commit is contained in:
parent
28de783c96
commit
cc09e53b6a
@ -30,6 +30,9 @@
|
||||
#include "Poco/SharedPtr.h"
|
||||
#include <cstddef>
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
#include <tuple>
|
||||
#endif
|
||||
|
||||
namespace Poco {
|
||||
namespace Data {
|
||||
@ -2104,6 +2107,131 @@ private:
|
||||
};
|
||||
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
|
||||
template<size_t N>
|
||||
struct TupleBind
|
||||
/// Helper for specialization of type handler for std::tuple
|
||||
{
|
||||
template<typename... T>
|
||||
static typename std::enable_if<N < sizeof...(T)>::type
|
||||
bind(std::size_t& pos, const std::tuple<T...>& t, AbstractBinder::Ptr pBinder, AbstractBinder::Direction dir)
|
||||
{
|
||||
using Type = typename std::tuple_element<N, std::tuple<T...>>::type;
|
||||
TypeHandler<Type>::bind(pos, std::get<N>(t), pBinder, dir);
|
||||
pos += TypeHandler<Type>::size();
|
||||
TupleBind<N+1>::bind(pos, t, pBinder, dir);
|
||||
}
|
||||
|
||||
template<typename... T>
|
||||
static typename std::enable_if<!(N < sizeof...(T))>::type
|
||||
bind(std::size_t& pos, const std::tuple<T...>& t, AbstractBinder::Ptr pBinder, AbstractBinder::Direction dir)
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
template<size_t N>
|
||||
struct TupleSize
|
||||
/// Helper for specialization of type handler for std::tuple
|
||||
{
|
||||
template<typename... T>
|
||||
static typename std::enable_if<N < sizeof...(T)>::type
|
||||
size(std::size_t& sz)
|
||||
{
|
||||
using Type = typename std::tuple_element<N, std::tuple<T...>>::type;
|
||||
sz += TypeHandler<Type>::size();
|
||||
TupleSize<N+1>::size(sz);
|
||||
}
|
||||
|
||||
template<typename... T>
|
||||
static typename std::enable_if<!(N < sizeof...(T))>::type
|
||||
size(std::size_t& sz)
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
template<size_t N>
|
||||
struct TupleExtract
|
||||
/// Helper for specialization of type handler for std::tuple
|
||||
{
|
||||
template<typename... T>
|
||||
static typename std::enable_if<N < sizeof...(T)>::type
|
||||
extract(std::size_t& pos, std::tuple<T...>& t, const std::tuple<T...>& defVal, AbstractExtractor::Ptr pExt)
|
||||
{
|
||||
using Type = typename std::tuple_element<N, std::tuple<T...>>::type;
|
||||
TypeHandler<Type>::extract(pos, std::get<N>(t), std::get<N>(defVal), pExt);
|
||||
pos += TypeHandler<Type>::size();
|
||||
TupleExtract<N+1>::extract(pos, t, defVal, pExt);
|
||||
}
|
||||
|
||||
template<typename... T>
|
||||
static typename std::enable_if<!(N < sizeof...(T))>::type
|
||||
extract(std::size_t& pos, std::tuple<T...>& t, const std::tuple<T...>& defVal, AbstractExtractor::Ptr pExt)
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
template<size_t N>
|
||||
struct TuplePrepare
|
||||
/// Helper for specialization of type handler for std::tuple
|
||||
{
|
||||
template<typename... T>
|
||||
static typename std::enable_if<N < sizeof...(T)>::type
|
||||
prepare(std::size_t& pos, const std::tuple<T...>& t, AbstractPreparator::Ptr pPreparator)
|
||||
{
|
||||
using Type = typename std::tuple_element<N, std::tuple<T...>>::type;
|
||||
TypeHandler<Type>::prepare(pos, std::get<N>(t), pPreparator);
|
||||
pos += TypeHandler<Type>::size();
|
||||
TuplePrepare<N+1>::prepare(pos, t, pPreparator);
|
||||
}
|
||||
|
||||
template<typename... T>
|
||||
static typename std::enable_if<!(N < sizeof...(T))>::type
|
||||
prepare(std::size_t& pos, const std::tuple<T...>& t, AbstractPreparator::Ptr pPreparator)
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
|
||||
template <typename...T>
|
||||
class TypeHandler<std::tuple<T...>>
|
||||
/// Specialization of type handler for std::tuple
|
||||
{
|
||||
public:
|
||||
static void bind(std::size_t pos, const std::tuple<T...> & t, AbstractBinder::Ptr pBinder, AbstractBinder::Direction dir)
|
||||
{
|
||||
poco_assert_dbg (!pBinder.isNull());
|
||||
TupleBind<0>::bind(pos, t, pBinder, dir);
|
||||
}
|
||||
|
||||
static std::size_t size()
|
||||
{
|
||||
std::size_t sz = 0;
|
||||
TupleSize<0>::size(sz);
|
||||
return sz;
|
||||
}
|
||||
|
||||
static void extract(std::size_t pos, std::tuple<T...>& t, const std::tuple<T...>& defVal, AbstractExtractor::Ptr pExt)
|
||||
{
|
||||
poco_assert_dbg (!pExt.isNull());
|
||||
TupleExtract<0>::extract(pos, t, defVal, pExt);
|
||||
}
|
||||
|
||||
static void prepare(std::size_t pos, const std::tuple<T...> & t, AbstractPreparator::Ptr pPrepare)
|
||||
{
|
||||
poco_assert_dbg (!pPrepare.isNull());
|
||||
TuplePrepare<0>::prepare(pos, t, pPrepare);
|
||||
}
|
||||
|
||||
private:
|
||||
TypeHandler();
|
||||
~TypeHandler();
|
||||
TypeHandler(const TypeHandler&);
|
||||
TypeHandler& operator=(const TypeHandler&);
|
||||
};
|
||||
|
||||
#endif // __cplusplus >= 201103L
|
||||
|
||||
} } // namespace Poco::Data
|
||||
|
||||
|
||||
|
@ -38,6 +38,10 @@
|
||||
#include <iomanip>
|
||||
#include <set>
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
#include <tuple>
|
||||
#endif
|
||||
|
||||
|
||||
using namespace Poco::Data::Keywords;
|
||||
|
||||
@ -1400,6 +1404,22 @@ void DataTest::testExternalBindingAndExtraction()
|
||||
}
|
||||
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
|
||||
void DataTest::testStdTuple()
|
||||
{
|
||||
using Row = std::tuple<std::string, std::string, int>;
|
||||
|
||||
Session sess(SessionFactory::instance().create("test", "cs"));
|
||||
Row person = std::make_tuple(std::string("Scott"), std::string("Washington, DC"), 42);
|
||||
sess << "INSERT INTO Person(name, address, age) VALUES (?, ?, ?)", use(person), now;
|
||||
std::vector<Row> rows;
|
||||
sess << "SELECT name, address, age FROM Person", into(rows) , now;
|
||||
}
|
||||
|
||||
#endif // __cplusplus >= 201103L
|
||||
|
||||
|
||||
void DataTest::setUp()
|
||||
{
|
||||
}
|
||||
@ -1430,7 +1450,11 @@ CppUnit::Test* DataTest::suite()
|
||||
CppUnit_addTest(pSuite, DataTest, testSimpleRowFormatter);
|
||||
CppUnit_addTest(pSuite, DataTest, testJSONRowFormatter);
|
||||
CppUnit_addTest(pSuite, DataTest, testDateAndTime);
|
||||
CppUnit_addTest(pSuite, DataTest, testExternalBindingAndExtraction);
|
||||
CppUnit_addTest(pSuite, DataTest, testExternalBindingAndExtraction);
|
||||
#if __cplusplus >= 201103L
|
||||
CppUnit_addTest(pSuite, DataTest, testStdTuple);
|
||||
#endif
|
||||
|
||||
|
||||
return pSuite;
|
||||
}
|
||||
|
@ -47,6 +47,10 @@ public:
|
||||
void testDateAndTime();
|
||||
void testExternalBindingAndExtraction();
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
void testStdTuple();
|
||||
#endif
|
||||
|
||||
void setUp();
|
||||
void tearDown();
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user