strconv.hxx
#ifndef PQXX_H_STRINGCONV
#define PQXX_H_STRINGCONV
#include "pqxx/compiler-public.hxx"
#include <limits>
#include <sstream>
#include <stdexcept>
namespace pqxx
{
template<typename T, typename = void> struct string_traits;
namespace internal
{
[[noreturn]] PQXX_LIBEXPORT void throw_null_conversion(
const std::string &type);
template<typename TYPE> struct type_name;
#define PQXX_DECLARE_TYPE_NAME(TYPE) \
template<> struct type_name<TYPE> \
{ static constexpr const char *value = #TYPE; }
PQXX_DECLARE_TYPE_NAME(bool);
PQXX_DECLARE_TYPE_NAME(short);
PQXX_DECLARE_TYPE_NAME(unsigned short);
PQXX_DECLARE_TYPE_NAME(int);
PQXX_DECLARE_TYPE_NAME(unsigned int);
PQXX_DECLARE_TYPE_NAME(long);
PQXX_DECLARE_TYPE_NAME(unsigned long);
PQXX_DECLARE_TYPE_NAME(long long);
PQXX_DECLARE_TYPE_NAME(unsigned long long);
PQXX_DECLARE_TYPE_NAME(float);
PQXX_DECLARE_TYPE_NAME(double);
PQXX_DECLARE_TYPE_NAME(long double);
PQXX_DECLARE_TYPE_NAME(char *);
PQXX_DECLARE_TYPE_NAME(const char *);
PQXX_DECLARE_TYPE_NAME(std::string);
PQXX_DECLARE_TYPE_NAME(const std::string);
PQXX_DECLARE_TYPE_NAME(std::stringstream);
#undef PQXX_DECLARE_TYPE_NAME
template<size_t N> struct type_name<char[N]>
{ static constexpr const char *value = "char[]"; };
template<typename TYPE> struct PQXX_LIBEXPORT builtin_traits
{
static constexpr const char *name() noexcept
{ return internal::type_name<TYPE>::value; }
static constexpr bool has_null() noexcept { return false; }
static bool is_null(TYPE) { return false; }
[[noreturn]] static TYPE null() { throw_null_conversion(name()); }
static void from_string(const char Str[], TYPE &Obj);
static std::string to_string(TYPE Obj);
};
} // namespace pqxx::internal
#define PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(TYPE) \
template<> struct PQXX_LIBEXPORT string_traits<TYPE> : \
internal::builtin_traits<TYPE> {};
PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(bool)
PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(short)
PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(unsigned short)
PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(int)
PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(unsigned int)
PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(long)
PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(unsigned long)
PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(long long)
PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(unsigned long long)
PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(float)
PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(double)
PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(long double)
#undef PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION
template<typename ENUM>
struct enum_traits
{
using underlying_type = typename std::underlying_type<ENUM>::type;
using underlying_traits = string_traits<underlying_type>;
static constexpr bool has_null() noexcept { return false; }
[[noreturn]] static ENUM null()
{ internal::throw_null_conversion("enum type"); }
static void from_string(const char Str[], ENUM &Obj)
{
underlying_type tmp;
underlying_traits::from_string(Str, tmp);
Obj = ENUM(tmp);
}
static std::string to_string(ENUM Obj)
{ return underlying_traits::to_string(underlying_type(Obj)); }
};
#define PQXX_DECLARE_ENUM_CONVERSION(ENUM) \
template<> \
struct string_traits<ENUM> : pqxx::enum_traits<ENUM> \
{ \
static constexpr const char *name() noexcept { return #ENUM; } \
[[noreturn]] static ENUM null() \
{ internal::throw_null_conversion(name()); } \
}
template<> struct PQXX_LIBEXPORT string_traits<const char *>
{
static constexpr const char *name() noexcept { return "const char *"; }
static constexpr bool has_null() noexcept { return true; }
static bool is_null(const char *t) { return t == nullptr; }
static const char *null() { return nullptr; }
static void from_string(const char Str[], const char *&Obj) { Obj = Str; }
static std::string to_string(const char *Obj) { return Obj; }
};
template<> struct PQXX_LIBEXPORT string_traits<char *>
{
static constexpr const char *name() noexcept { return "char *"; }
static constexpr bool has_null() noexcept { return true; }
static bool is_null(const char *t) { return t == nullptr; }
static const char *null() { return nullptr; }
// Don't allow this conversion since it breaks const-safety.
// static void from_string(const char Str[], char *&Obj);
static std::string to_string(char *Obj) { return Obj; }
};
template<size_t N> struct PQXX_LIBEXPORT string_traits<char[N]>
{
static constexpr const char *name() noexcept { return "char[]"; }
static constexpr bool has_null() noexcept { return true; }
static bool is_null(const char t[]) { return t == nullptr; }
static const char *null() { return nullptr; }
static std::string to_string(const char Obj[]) { return Obj; }
};
template<> struct PQXX_LIBEXPORT string_traits<std::string>
{
static constexpr const char *name() noexcept { return "string"; }
static constexpr bool has_null() noexcept { return false; }
static bool is_null(const std::string &) { return false; }
[[noreturn]] static std::string null()
{ internal::throw_null_conversion(name()); }
static void from_string(const char Str[], std::string &Obj) { Obj=Str; }
static std::string to_string(const std::string &Obj) { return Obj; }
};
template<> struct PQXX_LIBEXPORT string_traits<const std::string>
{
static constexpr const char *name() noexcept { return "const string"; }
static constexpr bool has_null() noexcept { return false; }
static bool is_null(const std::string &) { return false; }
[[noreturn]] static const std::string null()
{ internal::throw_null_conversion(name()); }
static const std::string to_string(const std::string &Obj) { return Obj; }
};
template<> struct PQXX_LIBEXPORT string_traits<std::stringstream>
{
static constexpr const char *name() noexcept { return "stringstream"; }
static constexpr bool has_null() noexcept { return false; }
static bool is_null(const std::stringstream &) { return false; }
[[noreturn]] static std::stringstream null()
{ internal::throw_null_conversion(name()); }
static void from_string(const char Str[], std::stringstream &Obj)
{ Obj.clear(); Obj << Str; }
static std::string to_string(const std::stringstream &Obj)
{ return Obj.str(); }
};
// TODO: Implement date conversions.
template<typename T>
inline void from_string(const char Str[], T &Obj)
{
if (Str == nullptr) throw std::runtime_error{"Attempt to read null string."};
string_traits<T>::from_string(Str, Obj);
}
template<typename T> inline void from_string(const char Str[], T &Obj, size_t)
{
return from_string(Str, Obj);
}
template<>
inline void from_string<std::string>( //[t00]
const char Str[],
std::string &Obj,
size_t len)
{
if (Str == nullptr) throw std::runtime_error{"Attempt to read null string."};
Obj.assign(Str, len);
}
template<typename T>
inline void from_string(const std::string &Str, T &Obj) //[t45]
{ from_string(Str.c_str(), Obj); }
template<typename T>
inline void from_string(const std::stringstream &Str, T &Obj) //[t00]
{ from_string(Str.str(), Obj); }
template<> inline void
from_string(const std::string &Str, std::string &Obj) //[t46]
{ Obj = Str; }
namespace internal
{
constexpr int digit_to_number(char c) noexcept { return c-'0'; }
constexpr char number_to_digit(int i) noexcept
{ return static_cast<char>(i+'0'); }
} // namespace pqxx::internal
template<typename T> inline std::string to_string(const T &Obj)
{ return string_traits<T>::to_string(Obj); }
} // namespace pqxx
#endif
pqxx::connection_base::encoding_id
int encoding_id() const
Get the connection's encoding, as a PostgreSQL-defined code.
Definition: connection_base.cxx:1417
pqxx::string_traits< const char * >::name
static constexpr const char * name() noexcept
Definition: strconv.hxx:195
pqxx::string_traits< std::stringstream >::has_null
static constexpr bool has_null() noexcept
Definition: strconv.hxx:251
pqxx::conversion_error
Value conversion failed, e.g. when converting "Hello" to int.
Definition: except.hxx:240
pqxx::transaction_base::exec
result exec(const std::string &Query, const std::string &Desc=std::string{})
Execute query.
Definition: transaction_base.cxx:249
pqxx::internal
Private namespace for libpqxx's internal use; do not access.
Definition: connection_base.hxx:43
pqxx::string_traits< std::stringstream >::from_string
static void from_string(const char Str[], std::stringstream &Obj)
Definition: strconv.hxx:255
pqxx::enum_traits::has_null
static constexpr bool has_null() noexcept
Definition: strconv.hxx:154
pqxx::cursor_base::accesspolicy
accesspolicy
Cursor access-pattern policy.
Definition: cursor.hxx:50
pqxx::string_traits< const char * >::is_null
static bool is_null(const char *t)
Definition: strconv.hxx:197
pqxx::cursor_base::forward_only
@ forward_only
Cursor can move forward only.
Definition: cursor.hxx:53
pqxx::internal::builtin_traits::to_string
static std::string to_string(TYPE Obj)
pqxx::string_traits< std::string >::has_null
static constexpr bool has_null() noexcept
Definition: strconv.hxx:230
pqxx::result
Result set containing data returned by a query or command.
Definition: result.hxx:69
pqxx::from_string
void from_string(const field &F, T &Obj)
Convert a field's string contents to another type.
Definition: field.hxx:365
pqxx::string_traits< char * >::has_null
static constexpr bool has_null() noexcept
Definition: strconv.hxx:207
pqxx::string_traits< std::stringstream >::is_null
static bool is_null(const std::stringstream &)
Definition: strconv.hxx:252
pqxx::cursor_base::all
static difference_type all() noexcept
Special value: read until end.
Definition: cursor.cxx:27
pqxx::string_traits< char * >::is_null
static bool is_null(const char *t)
Definition: strconv.hxx:208
pqxx::internal::type_name
Give a human-readable name for a type, at compile time.
Definition: strconv.hxx:67
pqxx::string_traits< const char * >::to_string
static std::string to_string(const char *Obj)
Definition: strconv.hxx:200
pqxx::string_traits< char * >::to_string
static std::string to_string(char *Obj)
Definition: strconv.hxx:214
pqxx::internal::enc_group
encoding_group enc_group(int libpq_enc_id)
Definition: encodings.cxx:637
pqxx::string_traits< std::string >::is_null
static bool is_null(const std::string &)
Definition: strconv.hxx:231
pqxx::string_traits< const std::string >::to_string
static const std::string to_string(const std::string &Obj)
Definition: strconv.hxx:245
pqxx::string_traits< char[N]>::is_null
static bool is_null(const char t[])
Definition: strconv.hxx:222
pqxx::transaction_base::quote_name
std::string quote_name(const std::string &identifier) const
Escape an SQL identifier for use in a query.
Definition: transaction_base.hxx:225
pqxx::cursor_base::updatepolicy
updatepolicy
Cursor update policy.
Definition: cursor.hxx:62
pqxx::string_traits< const std::string >::name
static constexpr const char * name() noexcept
Definition: strconv.hxx:240
pqxx::internal_error
Internal error in libpqxx library.
Definition: except.hxx:207
pqxx::enum_traits::underlying_type
typename std::underlying_type< ENUM >::type underlying_type
Definition: strconv.hxx:151
pqxx::internal::builtin_traits::has_null
static constexpr bool has_null() noexcept
Definition: strconv.hxx:106
pqxx::internal::number_to_digit
constexpr char number_to_digit(int i) noexcept
Definition: strconv.hxx:324
pqxx::string_traits< char[N]>::has_null
static constexpr bool has_null() noexcept
Definition: strconv.hxx:221
pqxx::enum_traits::to_string
static std::string to_string(ENUM Obj)
Definition: strconv.hxx:165
pqxx::string_traits< std::string >::from_string
static void from_string(const char Str[], std::string &Obj)
Definition: strconv.hxx:234
pqxx::string_traits< std::stringstream >::to_string
static std::string to_string(const std::stringstream &Obj)
Definition: strconv.hxx:257
pqxx::internal::builtin_traits::from_string
static void from_string(const char Str[], TYPE &Obj)
pqxx::enum_traits::from_string
static void from_string(const char Str[], ENUM &Obj)
Definition: strconv.hxx:158
pqxx::transaction_base::conn
connection_base & conn() const
Connection this transaction is running in.
Definition: transaction_base.hxx:492
pqxx::string_traits< const char * >::from_string
static void from_string(const char Str[], const char *&Obj)
Definition: strconv.hxx:199
pqxx::cursor_base::backward_all
static difference_type backward_all() noexcept
Special value: read backwards from current position back to origin.
Definition: cursor.cxx:35
pqxx::string_traits< std::stringstream >::name
static constexpr const char * name() noexcept
Definition: strconv.hxx:250
pqxx::string_traits< const std::string >::is_null
static bool is_null(const std::string &)
Definition: strconv.hxx:242
pqxx::internal::builtin_traits
Helper: string traits implementation for built-in types.
Definition: strconv.hxx:102
pqxx::string_traits< const std::string >::has_null
static constexpr bool has_null() noexcept
Definition: strconv.hxx:241
pqxx::string_traits< char[N]>::to_string
static std::string to_string(const char Obj[])
Definition: strconv.hxx:224
pqxx::string_traits< char * >::name
static constexpr const char * name() noexcept
Definition: strconv.hxx:206
pqxx::cursor_base::difference_type
result_difference_type difference_type
Definition: cursor.hxx:44
pqxx::string_traits< std::string >::name
static constexpr const char * name() noexcept
Definition: strconv.hxx:229
pqxx::internal::builtin_traits::name
static constexpr const char * name() noexcept
Definition: strconv.hxx:104
pqxx::to_string
std::string to_string(const field &Obj)
Convert a field to a string.
Definition: result.cxx:451
pqxx::string_traits< char[N]>::name
static constexpr const char * name() noexcept
Definition: strconv.hxx:220
pqxx::cursor_base
Common definitions for cursor types.
Definition: cursor.hxx:40
pqxx::cursor_base::owned
@ owned
Destroy SQL cursor when cursor object is closed at end of transaction.
Definition: cursor.hxx:92
pqxx::internal::builtin_traits::is_null
static bool is_null(TYPE)
Definition: strconv.hxx:107
pqxx::internal::digit_to_number
constexpr int digit_to_number(char c) noexcept
Compute numeric value of given textual digit (assuming that it is a digit)
Definition: strconv.hxx:323
pqxx::cursor_base::ownershippolicy
ownershippolicy
Cursor destruction policy.
Definition: cursor.hxx:89
pqxx::cursor_base::update
@ update
Cursor can be used to update data as well as read it.
Definition: cursor.hxx:67
pqxx::cursor_base::loose
@ loose
Leave SQL cursor in existence after close of object and transaction.
Definition: cursor.hxx:94
pqxx::string_traits< std::string >::to_string
static std::string to_string(const std::string &Obj)
Definition: strconv.hxx:235
pqxx::string_traits
Traits class for use in string conversions.
Definition: strconv.hxx:51
pqxx::transaction_base
Interface definition (and common code) for "transaction" classes.
Definition: transaction_base.hxx:136
pqxx
The home of all libpqxx classes, functions, templates, etc.
Definition: array.hxx:25
pqxx::usage_error
Error in usage of libpqxx library, similar to std::logic_error.
Definition: except.hxx:218
pqxx::internal::PQXX_DECLARE_TYPE_NAME
PQXX_DECLARE_TYPE_NAME(bool)
pqxx::enum_traits
Helper class for defining enum conversions.
Definition: strconv.hxx:149
pqxx::string_traits< const char * >::has_null
static constexpr bool has_null() noexcept
Definition: strconv.hxx:196
pqxx::internal::throw_null_conversion
void throw_null_conversion(const std::string &type)
Throw exception for attempt to convert null to given type.
Definition: strconv.cxx:58