4#if !defined(PQXX_HEADER_PRE)
5# error "Include libpqxx headers as <pqxx/header>, not <pqxx/header.hxx>."
10#include "pqxx/internal/array-composite.hxx"
11#include "pqxx/internal/concat.hxx"
28 template<
typename TYPE>
constexpr bool extends_up_to(TYPE
const &)
const
46 throw argument_error{
"Got null value as an inclusive range bound."};
49 [[nodiscard]]
constexpr TYPE
const &
get() const &noexcept {
return m_value; }
55 return not(value < m_value);
62 return not(m_value < value);
81 throw argument_error{
"Got null value as an exclusive range bound."};
84 [[nodiscard]]
constexpr TYPE
const &
get() const &noexcept {
return m_value; }
90 return m_value < value;
97 return value < m_value;
143 return not std::holds_alternative<no_bound>(m_bound);
149 return std::holds_alternative<inclusive_bound<TYPE>>(m_bound);
155 return std::holds_alternative<exclusive_bound<TYPE>>(m_bound);
163 [&
value](
auto const &bound) {
return bound.extends_down_to(
value); },
172 [&
value](
auto const &bound) {
return bound.extends_up_to(
value); },
177 [[nodiscard]]
constexpr TYPE
const *
value() const &noexcept
180 [](
auto const &bound)
noexcept {
181 using bound_t = std::decay_t<
decltype(bound)>;
182 if constexpr (std::is_same_v<bound_t, no_bound>)
183 return static_cast<TYPE
const *
>(
nullptr);
224 m_lower{lower}, m_upper{upper}
230 "Range's lower bound (", *lower.
value(),
231 ") is greater than its upper bound (", *upper.
value(),
").")};
241 m_upper{exclusive_bound<TYPE>{TYPE{}}}
247 return (this->lower_bound() == rhs.
lower_bound() and
249 (this->empty() and rhs.
empty());
272 return (m_lower.is_exclusive() or m_upper.is_exclusive()) and
273 m_lower.is_limited() and m_upper.is_limited() and
274 not(*m_lower.value() < *m_upper.value());
281 return m_lower.extends_down_to(value) and m_upper.extends_up_to(value);
291 return (*
this & other) == other;
312 if (not this->lower_bound().is_limited())
315 lower = this->lower_bound();
316 else if (*this->lower_bound().value() < *other.
lower_bound().value())
318 else if (*other.
lower_bound().value() < *this->lower_bound().value())
319 lower = this->lower_bound();
320 else if (this->lower_bound().is_exclusive())
321 lower = this->lower_bound();
326 if (not this->upper_bound().is_limited())
329 upper = this->upper_bound();
330 else if (*other.
upper_bound().value() < *this->upper_bound().value())
332 else if (*this->upper_bound().value() < *other.
upper_bound().value())
333 upper = this->upper_bound();
334 else if (this->upper_bound().is_exclusive())
335 upper = this->upper_bound();
340 lower.is_limited() and upper.is_limited() and
341 (*upper.value() < *lower.value()))
344 return {lower, upper};
351 if (lower_bound().is_inclusive())
353 else if (lower_bound().is_exclusive())
356 if (upper_bound().is_inclusive())
358 else if (upper_bound().is_exclusive())
361 return {lower, upper};
375 [[nodiscard]]
static inline zview
386 if ((end - begin) <= internal::ssize(s_empty))
388 char *here = begin + s_empty.copy(begin, std::size(s_empty));
398 (
static_cast<char>(value.
lower_bound().is_inclusive() ?
'[' :
'('));
401 if (lower !=
nullptr)
406 if (upper !=
nullptr)
408 if ((end - here) < 2)
411 static_cast<char>(value.
upper_bound().is_inclusive() ?
']' :
')');
419 if (std::size(
text) < 3)
421 bool left_inc{
false};
424 case '[': left_inc =
true;
break;
431 (std::size(
text) != std::size(s_empty)) or
432 (
text[1] !=
'm' and
text[1] !=
'M') or
433 (
text[2] !=
'p' and
text[2] !=
'P') or
434 (
text[3] !=
't' and
text[3] !=
'T') or
435 (
text[4] !=
'y' and
text[4] !=
'Y'))
443 auto scan{internal::get_glyph_scanner(internal::encoding_group::UTF8)};
446 std::size_t index{0};
448 static constexpr std::size_t last{1};
452 std::optional<TYPE> lower, upper;
454 internal::parse_composite_field(index,
text, pos, lower, scan, last);
455 internal::parse_composite_field(index,
text, pos, upper, scan, last);
458 if (pos != std::size(
text))
460 char const closing{
text[pos - 1]};
461 if (closing !=
')' and closing !=
']')
463 bool const right_inc{closing ==
']'};
481 return {lower_bound, upper_bound};
484 [[nodiscard]]
static inline constexpr std::size_t
487 TYPE
const *lower{value.lower_bound().value()},
488 *upper{value.upper_bound().value()};
489 std::size_t
const lsz{
494 return std::size(s_empty) + 1;
496 return 1 + lsz + 1 + usz + 2;
500 static constexpr zview s_empty{
"empty"_zv};
501 static constexpr auto s_overrun{
"Not enough space in buffer for range."_zv};
504 static std::string err_bad_input(std::string_view text)
506 return internal::concat(
"Invalid range input: '", text,
"'");
The home of all libpqxx classes, functions, templates, etc.
Definition: array.hxx:27
constexpr bool is_null(TYPE const &value) noexcept
Is value null?
Definition: strconv.hxx:370
zview generic_to_buf(char *begin, char *end, TYPE const &value)
Implement string_traits<TYPE>::to_buf by calling into_buf.
Definition: strconv.hxx:442
Invalid argument passed to libpqxx, similar to std::invalid_argument.
Definition: except.hxx:181
Value conversion failed, e.g. when converting "Hello" to int.
Definition: except.hxx:188
Could not convert value to string: not enough buffer space.
Definition: except.hxx:195
Something is out of range, similar to std::out_of_range.
Definition: except.hxx:202
An unlimited boundary value to a pqxx::range.
Definition: range.hxx:23
constexpr bool extends_down_to(TYPE const &) const
Definition: range.hxx:24
constexpr bool extends_up_to(TYPE const &) const
Definition: range.hxx:28
An inclusive boundary value to a pqxx::range.
Definition: range.hxx:40
bool extends_up_to(TYPE const &value) const
Would this bound, as an upper bound, include value?
Definition: range.hxx:60
bool extends_down_to(TYPE const &value) const
Would this bound, as a lower bound, include value?
Definition: range.hxx:53
constexpr TYPE const & get() const &noexcept
Definition: range.hxx:49
inclusive_bound(TYPE const &value)
Definition: range.hxx:43
An exclusive boundary value to a pqxx::range.
Definition: range.hxx:75
exclusive_bound(TYPE const &value)
Definition: range.hxx:78
bool extends_down_to(TYPE const &value) const
Would this bound, as a lower bound, include value?
Definition: range.hxx:88
constexpr TYPE const & get() const &noexcept
Definition: range.hxx:84
bool extends_up_to(TYPE const &value) const
Would this bound, as an upper bound, include value?
Definition: range.hxx:95
A range boundary value.
Definition: range.hxx:110
bool extends_down_to(TYPE const &value) const
Would this bound, as a lower bound, include value?
Definition: range.hxx:160
range_bound(range_bound &&)=default
constexpr bool is_exclusive() const noexcept
Is this boundary an exclusive one?
Definition: range.hxx:153
bool extends_up_to(TYPE const &value) const
Would this bound, as an upper bound, include value?
Definition: range.hxx:169
constexpr bool is_limited() const noexcept
Is this a finite bound?
Definition: range.hxx:141
constexpr TYPE const * value() const &noexcept
Return bound value, or nullptr if it's not limited.
Definition: range.hxx:177
range_bound(inclusive_bound< TYPE > const &bound)
Definition: range.hxx:116
range_bound(range_bound const &)=default
range_bound & operator=(range_bound const &)=default
range_bound(exclusive_bound< TYPE > const &bound)
Definition: range.hxx:118
range_bound(no_bound)
Definition: range.hxx:114
constexpr bool is_inclusive() const noexcept
Is this boundary an inclusive one?
Definition: range.hxx:147
bool operator==(range_bound const &rhs) const
Definition: range.hxx:125
range_bound & operator=(range_bound &&)=default
bool operator!=(range_bound const &rhs) const
Definition: range.hxx:136
A C++ equivalent to PostgreSQL's range types.
Definition: range.hxx:216
range(range_bound< TYPE > lower, range_bound< TYPE > upper)
Create a range.
Definition: range.hxx:223
range(range const &)=default
range & operator=(range &&)=default
range & operator=(range const &)=default
constexpr range_bound< TYPE > const & upper_bound() const &noexcept
Definition: range.hxx:300
bool contains(range< TYPE > const &other) const
Does this range encompass all of other?
Definition: range.hxx:289
bool operator==(range const &rhs) const
Definition: range.hxx:245
bool empty() const
Is this range clearly empty?
Definition: range.hxx:270
bool contains(TYPE value) const
Does this range encompass value?
Definition: range.hxx:279
range()
Create an empty range.
Definition: range.hxx:239
bool operator!=(range const &rhs) const
Definition: range.hxx:253
range operator&(range const &other) const
Intersection of two ranges.
Definition: range.hxx:309
constexpr range_bound< TYPE > const & lower_bound() const &noexcept
Definition: range.hxx:295
static constexpr std::size_t size_buffer(range< TYPE > const &value) noexcept
Definition: range.hxx:485
static char * into_buf(char *begin, char *end, range< TYPE > const &value)
Definition: range.hxx:382
static zview to_buf(char *begin, char *end, range< TYPE > const &value)
Definition: range.hxx:376
static range< TYPE > from_string(std::string_view text)
Definition: range.hxx:417
Traits describing a type's "null value," if any.
Definition: strconv.hxx:93
Nullness traits describing a type which does not have a null value.
Definition: strconv.hxx:115
Traits class for use in string conversions.
Definition: strconv.hxx:155
Marker-type wrapper: zero-terminated std::string_view.
Definition: zview.hxx:38