Skip to content

Instantly share code, notes, and snippets.

@JadeMatrix
Last active June 10, 2018 06:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JadeMatrix/1f01dacc650f233165a0d3eead3a5098 to your computer and use it in GitHub Desktop.
Save JadeMatrix/1f01dacc650f233165a0d3eead3a5098 to your computer and use it in GitHub Desktop.
libpqxx tablewriter tuple support proof-of-concept
#include <iostream>
#include <string>
#include <type_traits> // std::enable_if
#include <utility> // std::size_t
#include <tuple> // std::tuple_size, std::get
#include <vector>
using std::to_string;
std::string to_string( const char* c ) { return std::string{ c }; }
std::string to_string( bool b ) { return b ? "true" : "false"; }
const std::string& to_string( const std::string& s ) { return s; }
namespace pqxx
{
template<typename ITER, typename ACCESS> inline
std::string separated_list( //[t00]
const std::string &sep,
ITER begin,
ITER end,
ACCESS access)
{
std::string result;
if (begin != end)
{
result = to_string(access(begin));
for (++begin; begin != end; ++begin)
{
result += sep;
result += to_string(access(begin));
}
}
return result;
}
template<typename ITER> inline std::string
separated_list(const std::string &sep, ITER begin, ITER end) //[t00]
{ return separated_list(sep, begin, end, [](ITER i){ return *i; }); }
template< typename CONTAINER > inline auto
// > inline std::string
separated_list(const std::string &sep, const CONTAINER &c) //[t10]
-> typename std::enable_if<
(
!std::is_void<decltype(begin(c))>::value
&& !std::is_void<decltype(end(c))>::value
),
std::string
>::type
// { return separated_list(sep, c.begin(), c.end()); }
{ return separated_list(sep, begin(c), end(c)); }
template<
typename CONTAINER,
typename ACCESS
> inline auto
separated_list(const std::string &sep, const CONTAINER &c, ACCESS access)
-> typename std::enable_if<
(
!std::is_void<decltype(begin(c))>::value
&& !std::is_void<decltype(end(c))>::value
),
std::string
>::type
{
return separated_list(sep, begin(c), end(c), access);
}
struct passthrough_access
{
template<typename T> constexpr auto operator()( T t_p ) const
-> decltype( *t_p )
{
return *t_p;
}
};
template<
typename TUPLE,
std::size_t INDEX = 0,
typename ACCESS,
typename std::enable_if<
(INDEX == std::tuple_size<TUPLE>::value-1),
int
>::type = 0
> inline std::string
separated_list(const std::string &sep, const TUPLE &t, const ACCESS& access)
{ return to_string(access(&std::get<INDEX>(t))); }
template<
typename TUPLE,
std::size_t INDEX = 0,
typename ACCESS,
typename std::enable_if<
(INDEX < std::tuple_size<TUPLE>::value-1),
int
>::type = 0
> inline std::string
separated_list(const std::string &sep, const TUPLE &t, const ACCESS& access)
{
return to_string(access(&std::get<INDEX>(t)))
+ sep
+ separated_list<TUPLE, INDEX+1>(sep, t, access);
}
template<
typename TUPLE,
std::size_t INDEX = 0,
typename std::enable_if<
(INDEX <= std::tuple_size<TUPLE>::value),
int
>::type = 0
> inline std::string
separated_list(const std::string &sep, const TUPLE &t)
// { return to_string(std::get<INDEX>(t)); }
{ return separated_list(sep, t, passthrough_access{}); }
}
template< typename T > std::string escape_any(
const T& v,
const std::string& nullval
)
{
return std::string{ "esc:\"" } + to_string( v ) + "\"";
}
class Escaper
{
const std::string &m_null;
public:
explicit Escaper(const std::string &null) : m_null(null) {}
template<typename IT> std::string operator()(IT i) const
{
return escape_any(*i, m_null);
}
};
int main( int argc, char* argv[] )
{
auto ilist = { 1, 421, 51 };
std::string string_array[] = { "hello", "world" };
std::cout
<< pqxx::separated_list( ", ", std::make_tuple( 1, "hello", true, 13.75f ) )
<< std::endl
<< pqxx::separated_list( ", ", std::make_tuple( 52345 ) )
<< std::endl
<< pqxx::separated_list( ", ", ilist )
<< std::endl
<< pqxx::separated_list( ", ", std::vector< int >{ ilist } )
<< std::endl
<< pqxx::separated_list( ", ", string_array )
<< std::endl
<< pqxx::separated_list( ", ", ilist, Escaper( "nullstr" ) )
<< std::endl
<< pqxx::separated_list( ", ", std::make_tuple( 1, "hello", true, 13.75f ), Escaper( "nullstr" ) )
<< std::endl
;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment