mirror of
https://github.com/pocoproject/poco.git
synced 2025-03-31 16:04:27 +02: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 "Poco/SharedPtr.h"
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
|
||||||
|
#if __cplusplus >= 201103L
|
||||||
|
#include <tuple>
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco {
|
||||||
namespace Data {
|
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
|
} } // namespace Poco::Data
|
||||||
|
|
||||||
|
|
||||||
|
@ -38,6 +38,10 @@
|
|||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
|
#if __cplusplus >= 201103L
|
||||||
|
#include <tuple>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
using namespace Poco::Data::Keywords;
|
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()
|
void DataTest::setUp()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -1430,7 +1450,11 @@ CppUnit::Test* DataTest::suite()
|
|||||||
CppUnit_addTest(pSuite, DataTest, testSimpleRowFormatter);
|
CppUnit_addTest(pSuite, DataTest, testSimpleRowFormatter);
|
||||||
CppUnit_addTest(pSuite, DataTest, testJSONRowFormatter);
|
CppUnit_addTest(pSuite, DataTest, testJSONRowFormatter);
|
||||||
CppUnit_addTest(pSuite, DataTest, testDateAndTime);
|
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;
|
return pSuite;
|
||||||
}
|
}
|
||||||
|
@ -47,6 +47,10 @@ public:
|
|||||||
void testDateAndTime();
|
void testDateAndTime();
|
||||||
void testExternalBindingAndExtraction();
|
void testExternalBindingAndExtraction();
|
||||||
|
|
||||||
|
#if __cplusplus >= 201103L
|
||||||
|
void testStdTuple();
|
||||||
|
#endif
|
||||||
|
|
||||||
void setUp();
|
void setUp();
|
||||||
void tearDown();
|
void tearDown();
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user