libpqxx
util.hxx
1 
11 #ifndef PQXX_H_UTIL
12 #define PQXX_H_UTIL
13 
14 #include "pqxx/compiler-public.hxx"
15 
16 #include <cstdio>
17 #include <cctype>
18 #include <iterator>
19 #include <memory>
20 #include <stdexcept>
21 #include <string>
22 #include <type_traits>
23 #include <typeinfo>
24 #include <vector>
25 
26 #include "pqxx/strconv.hxx"
27 
28 
30 namespace pqxx {}
31 
32 #include <pqxx/internal/libpq-forward.hxx>
33 
34 
35 namespace pqxx
36 {
38 template<typename T> inline void ignore_unused(T) {}
39 
40 
42 
44 struct PQXX_LIBEXPORT thread_safety_model
45 {
47  bool have_safe_strerror = true;
48 
50  bool safe_libpq;
51 
53  bool safe_query_cancel = true;
54 
56  bool safe_result_copy = true;
57 
59 
66 
68  std::string description;
69 };
70 
71 
73 PQXX_LIBEXPORT thread_safety_model describe_thread_safety() noexcept;
74 
75 
77 constexpr oid oid_none = 0;
78 
79 
84 
86 
94 template<typename ITER, typename ACCESS> inline
95 std::string separated_list( //[t00]
96  const std::string &sep,
97  ITER begin,
98  ITER end,
99  ACCESS access)
100 {
101  std::string result;
102  if (begin != end)
103  {
104  result = to_string(access(begin));
105  for (++begin; begin != end; ++begin)
106  {
107  result += sep;
108  result += to_string(access(begin));
109  }
110  }
111  return result;
112 }
113 
114 
116 template<typename ITER> inline std::string
117 separated_list(const std::string &sep, ITER begin, ITER end) //[t00]
118  { return separated_list(sep, begin, end, [](ITER i){ return *i; }); }
119 
120 
122 template<typename CONTAINER> inline auto
123 separated_list(const std::string &sep, const CONTAINER &c) //[t10]
124  /*
125  Always std::string; necessary because SFINAE doesn't work with the
126  contents of function bodies, so the check for iterability has to be in
127  the signature.
128  */
129  -> typename std::enable_if<
130  (
131  not std::is_void<decltype(std::begin(c))>::value
132  and not std::is_void<decltype(std::end(c))>::value
133  ),
134  std::string
135  >::type
136 {
137  return separated_list(sep, std::begin(c), std::end(c));
138 }
139 
140 
141 namespace internal
142 {
144 {
145  template<typename T> constexpr auto operator()( T t_p ) const
146  -> decltype( *t_p )
147  {
148  return *t_p;
149  }
150 };
151 }
152 
154 template<
155  typename TUPLE,
156  std::size_t INDEX=0,
157  typename ACCESS,
158  typename std::enable_if<
159  (INDEX == std::tuple_size<TUPLE>::value-1),
160  int
161  >::type=0
162 >
163 inline std::string
165  const std::string & /* sep */,
166  const TUPLE &t,
167  const ACCESS& access
168 )
169 {
170  return to_string(access(&std::get<INDEX>(t)));
171 }
172 
173 template<
174  typename TUPLE,
175  std::size_t INDEX=0,
176  typename ACCESS,
177  typename std::enable_if<
178  (INDEX < std::tuple_size<TUPLE>::value-1),
179  int
180  >::type=0
181 >
182 inline std::string
183 separated_list(const std::string &sep, const TUPLE &t, const ACCESS& access)
184 {
185  return
186  to_string(access(&std::get<INDEX>(t))) +
187  sep +
188  separated_list<TUPLE, INDEX+1>(sep, t, access);
189 }
190 
191 template<
192  typename TUPLE,
193  std::size_t INDEX=0,
194  typename std::enable_if<
195  (INDEX <= std::tuple_size<TUPLE>::value),
196  int
197  >::type=0
198 >
199 inline std::string
200 separated_list(const std::string &sep, const TUPLE &t)
201 {
203 }
205 
206 
208 
217 namespace internal
218 {
219 PQXX_LIBEXPORT void freepqmem(const void *) noexcept;
220 template<typename P> inline void freepqmem_templated(P *p) noexcept
221 {
222  freepqmem(p);
223 }
224 
225 PQXX_LIBEXPORT void freemallocmem(const void *) noexcept;
226 template<typename P> inline void freemallocmem_templated(P *p) noexcept
227 {
228  freemallocmem(p);
229 }
230 
231 
233 
245 class PQXX_LIBEXPORT namedclass
246 {
247 public:
248  explicit namedclass(const std::string &Classname) :
249  m_classname{Classname},
250  m_name{}
251  {
252  }
253 
254  namedclass(const std::string &Classname, const std::string &Name) :
255  m_classname{Classname},
256  m_name{Name}
257  {
258  }
259 
261  const std::string &name() const noexcept { return m_name; } //[t01]
262 
264  const std::string &classname() const noexcept //[t73]
265  { return m_classname; }
266 
268  std::string description() const;
269 
270 private:
271  std::string m_classname, m_name;
272 };
273 
274 
275 PQXX_PRIVATE void CheckUniqueRegistration(
276  const namedclass *New, const namedclass *Old);
277 PQXX_PRIVATE void CheckUniqueUnregistration(
278  const namedclass *New, const namedclass *Old);
279 
280 
282 
285 template<typename GUEST>
286 class unique
287 {
288 public:
289  unique() =default;
290  unique(const unique &) =delete;
291  unique &operator=(const unique &) =delete;
292 
293  GUEST *get() const noexcept { return m_guest; }
294 
295  void register_guest(GUEST *G)
296  {
297  CheckUniqueRegistration(G, m_guest);
298  m_guest = G;
299  }
300 
301  void unregister_guest(GUEST *G)
302  {
303  CheckUniqueUnregistration(G, m_guest);
304  m_guest = nullptr;
305  }
306 
307 private:
308  GUEST *m_guest = nullptr;
309 };
310 
311 
313 
316 PQXX_LIBEXPORT void sleep_seconds(int);
317 
318 } // namespace internal
319 } // namespace pqxx
320 
321 #endif
void CheckUniqueRegistration(const namedclass *New, const namedclass *Old)
Definition: util.cxx:69
bool safe_libpq
Is the underlying libpq build thread-safe?
Definition: util.hxx:50
void ignore_unused(T)
Suppress compiler warning about an unused item.
Definition: util.hxx:38
void freepqmem(const void *) noexcept
Definition: util.cxx:103
std::string description
A human-readable description of any thread-safety issues.
Definition: util.hxx:68
namedclass(const std::string &Classname)
Definition: util.hxx:248
void CheckUniqueUnregistration(const namedclass *New, const namedclass *Old)
Definition: util.cxx:85
Ensure proper opening/closing of GUEST objects related to a "host" object.
Definition: util.hxx:286
thread_safety_model describe_thread_safety() noexcept
Describe thread safety available in this build.
Definition: util.cxx:28
namedclass(const std::string &Classname, const std::string &Name)
Definition: util.hxx:254
STL namespace.
const std::string & name() const noexcept
Object name, or the empty string if no name was given.
Definition: util.hxx:261
std::string to_string(const field &Obj)
Convert a field to a string.
Definition: result.cxx:448
Descriptor of library&#39;s thread-safety model.
Definition: util.hxx:44
constexpr oid oid_none
The "null" oid.
Definition: util.hxx:77
Helper base class: object descriptions for error messages and such.
Definition: util.hxx:245
void freemallocmem_templated(P *p) noexcept
Definition: util.hxx:226
const std::string & classname() const noexcept
Class name.
Definition: util.hxx:264
void freepqmem_templated(P *p) noexcept
Definition: util.hxx:220
constexpr auto operator()(T t_p) const -> decltype(*t_p)
Definition: util.hxx:145
bool safe_kerberos
Is Kerberos thread-safe?
Definition: util.hxx:65
Definition: util.hxx:143
void freemallocmem(const void *) noexcept
Definition: util.cxx:109
void sleep_seconds(int)
Sleep for the given number of seconds.
Definition: util.cxx:115
std::string separated_list(const std::string &sep, ITER begin, ITER end, ACCESS access)
Represent sequence of values as a string, joined by a given separator.
Definition: util.hxx:95
The home of all libpqxx classes, functions, templates, etc.
Definition: array.hxx:25
void register_guest(GUEST *G)
Definition: util.hxx:295
Result set containing data returned by a query or command.
Definition: result.hxx:69
void unregister_guest(GUEST *G)
Definition: util.hxx:301