6 #include "pqxx/internal/array-composite.hxx" 7 #include "pqxx/internal/concat.hxx" 24 template<
typename TYPE> constexpr
bool extends_up_to(TYPE
const &)
const 42 throw argument_error{
"Got null value as an inclusive range bound."};
45 [[nodiscard]] TYPE
const &
get()
const &noexcept {
return m_value; }
50 return not(value < m_value);
56 return not(m_value < value);
75 throw argument_error{
"Got null value as an exclusive range bound."};
78 [[nodiscard]] TYPE
const &
get()
const &noexcept {
return m_value; }
83 return m_value < value;
89 return value < m_value;
113 if (this->is_limited())
116 (*this->value() == *rhs.
value()));
128 return not std::holds_alternative<no_bound>(m_bound);
134 return std::holds_alternative<inclusive_bound<TYPE>>(m_bound);
140 return std::holds_alternative<exclusive_bound<TYPE>>(m_bound);
147 [&value](
auto const &bound) {
return bound.extends_down_to(value); },
155 [&value](
auto const &bound) {
return bound.extends_up_to(value); },
160 [[nodiscard]] TYPE
const *
value() const &noexcept
163 [](
auto const &bound) noexcept {
164 using bound_t = std::decay_t<decltype(bound)>;
165 if constexpr (std::is_same_v<bound_t, no_bound>)
166 return static_cast<TYPE
const *
>(
nullptr);
207 m_lower{lower}, m_upper{upper}
210 lower.is_limited() and upper.is_limited() and
211 (*upper.value() < *lower.value()))
213 "Range's lower bound (", *lower.value(),
214 ") is greater than its upper bound (", *upper.value(),
").")};
228 return (this->lower_bound() == rhs.
lower_bound() and
230 (this->empty() and rhs.
empty());
251 return (m_lower.is_exclusive() or m_upper.is_exclusive()) and
252 m_lower.is_limited() and m_upper.is_limited() and
253 not(*m_lower.value() < *m_upper.value());
259 return m_lower.extends_down_to(value) and m_upper.extends_up_to(value);
268 return (*
this & other) == other;
286 if (not this->lower_bound().is_limited())
289 lower = this->lower_bound();
290 else if (*this->lower_bound().value() < *other.
lower_bound().value())
292 else if (*other.
lower_bound().value() < *this->lower_bound().value())
293 lower = this->lower_bound();
294 else if (this->lower_bound().is_exclusive())
295 lower = this->lower_bound();
300 if (not this->upper_bound().is_limited())
303 upper = this->upper_bound();
304 else if (*other.
upper_bound().value() < *this->upper_bound().value())
306 else if (*this->upper_bound().value() < *other.
upper_bound().value())
307 upper = this->upper_bound();
308 else if (this->upper_bound().is_exclusive())
309 upper = this->upper_bound();
314 lower.is_limited() and upper.is_limited() and
315 (*upper.value() < *lower.value()))
318 return {lower, upper};
325 if (lower_bound().is_inclusive())
327 else if (lower_bound().is_exclusive())
330 if (upper_bound().is_inclusive())
332 else if (upper_bound().is_exclusive())
335 return {lower, upper};
349 [[nodiscard]]
static inline zview 362 char *here = begin + s_empty.copy(begin, std::size(s_empty));
372 (
static_cast<char>(value.
lower_bound().is_inclusive() ?
'[' :
'('));
375 if (lower !=
nullptr)
380 if (upper !=
nullptr)
382 if ((end - here) < 2)
385 static_cast<char>(value.
upper_bound().is_inclusive() ?
']' :
')');
393 if (std::size(text) < 3)
395 bool left_inc{
false};
398 case '[': left_inc =
true;
break;
405 (std::size(text) != std::size(s_empty)) or
406 (text[1] !=
'm' and text[1] !=
'M') or
407 (text[2] !=
'p' and text[2] !=
'P') or
408 (text[3] !=
't' and text[3] !=
'T') or
409 (text[4] !=
'y' and text[4] !=
'Y'))
420 std::size_t index{0};
423 constexpr std::size_t last{1};
427 std::optional<TYPE> lower, upper;
429 internal::parse_composite_field(index, text, pos, lower, scan, last);
430 internal::parse_composite_field(index, text, pos, upper, scan, last);
433 if (pos != std::size(text))
435 char const closing{text[pos - 1]};
436 if (closing !=
')' and closing !=
']')
438 bool const right_inc{closing ==
']'};
456 return {lower_bound, upper_bound};
459 [[nodiscard]]
static inline std::size_t
462 TYPE
const *lower{value.lower_bound().value()},
463 *upper{value.upper_bound().value()};
464 std::size_t
const lsz{
469 return std::size(s_empty) + 1;
471 return 1 + lsz + 1 + usz + 2;
476 static constexpr
zview s_empty{
"empty"_zv};
478 static constexpr
auto s_overrun{
"Not enough space in buffer for range."_zv};
481 static std::string err_bad_input(std::string_view
text)
483 return internal::concat(
"Invalid range input: '", text,
"'");
Could not convert value to string: not enough buffer space.
Definition: except.hxx:182
bool is_exclusive() const noexcept
Is this boundary an exclusive one?
Definition: range.hxx:138
range_bound(exclusive_bound< TYPE > const &bound)
Definition: range.hxx:107
An exclusive boundary value to a pqxx::range.
Definition: range.hxx:68
bool operator!=(range const &rhs) const
Definition: range.hxx:233
auto ssize(T const &c)
Transitional: std::ssize(), or custom implementation if not available.
Definition: util.hxx:439
bool extends_up_to(TYPE const &value) const
Would this bound, as an upper bound, include value?
Definition: range.hxx:54
range_bound< TYPE > const & upper_bound() const &noexcept
Definition: range.hxx:275
constexpr bool extends_up_to(TYPE const &) const
Definition: range.hxx:24
bool is_null(TYPE const &value) noexcept
Is value null?
Definition: strconv.hxx:364
bool empty() const
Is this range clearly empty?
Definition: range.hxx:249
Nullness traits describing a type which does not have a null value.
Definition: strconv.hxx:110
TYPE const * value() const &noexcept
Return bound value, or nullptr if it's not limited.
Definition: range.hxx:160
range_bound(inclusive_bound< TYPE > const &bound)
Definition: range.hxx:106
zview generic_to_buf(char *begin, char *end, TYPE const &value)
Implement string_traits<TYPE>::to_buf by calling into_buf.
Definition: strconv.hxx:439
bool is_inclusive() const noexcept
Is this boundary an inclusive one?
Definition: range.hxx:132
bool extends_up_to(TYPE const &value) const
Would this bound, as an upper bound, include value?
Definition: range.hxx:152
static char * into_buf(char *begin, char *end, range< TYPE > const &value)
Definition: range.hxx:356
bool extends_up_to(TYPE const &value) const
Would this bound, as an upper bound, include value?
Definition: range.hxx:87
An unlimited boundary value to a pqxx::range.
Definition: range.hxx:18
static char * into_buf(char *begin, char *end, TYPE const &value)
Write value's string representation into buffer at begin.
bool extends_down_to(TYPE const &value) const
Would this bound, as a lower bound, include value?
Definition: range.hxx:81
bool extends_down_to(TYPE const &value) const
Would this bound, as a lower bound, include value?
Definition: range.hxx:144
bool contains(range< TYPE > const &other) const
Does this range encompass all of other?
Definition: range.hxx:266
bool extends_down_to(TYPE const &value) const
Would this bound, as a lower bound, include value?
Definition: range.hxx:48
inclusive_bound(TYPE const &value)
Definition: range.hxx:39
range_bound< TYPE > const & lower_bound() const &noexcept
Definition: range.hxx:271
Marker-type wrapper: zero-terminated std::string_view.
Definition: zview.hxx:37
A C++ equivalent to PostgreSQL's range types.
Definition: range.hxx:198
Value conversion failed, e.g. when converting "Hello" to int.
Definition: except.hxx:175
An inclusive boundary value to a pqxx::range.
Definition: range.hxx:35
exclusive_bound(TYPE const &value)
Definition: range.hxx:72
bool is_limited() const noexcept
Is this a finite bound?
Definition: range.hxx:126
static std::size_t size_buffer(range< TYPE > const &value) noexcept
Definition: range.hxx:460
bool contains(TYPE value) const
Does this range encompass value?
Definition: range.hxx:257
constexpr bool extends_down_to(TYPE const &) const
Definition: range.hxx:20
static zview to_buf(char *begin, char *end, range< TYPE > const &value)
Definition: range.hxx:350
bool operator==(range_bound const &rhs) const
Definition: range.hxx:111
static std::size_t size_buffer(TYPE const &value) noexcept
Estimate how much buffer space is needed to represent value.
Traits describing a type's "null value," if any.
Definition: strconv.hxx:88
PQXX_PURE glyph_scanner_func * get_glyph_scanner(encoding_group enc)
Definition: encodings.cxx:785
bool operator!=(range_bound const &rhs) const
Definition: range.hxx:121
range()
Create an empty range.
Definition: range.hxx:221
range_bound(no_bound)
Definition: range.hxx:105
The home of all libpqxx classes, functions, templates, etc.
Definition: array.hxx:22
Something is out of range, similar to std::out_of_range.
Definition: except.hxx:189
A range boundary value.
Definition: range.hxx:101
Invalid argument passed to libpqxx, similar to std::invalid_argument.
Definition: except.hxx:168
Traits class for use in string conversions.
Definition: strconv.hxx:152
range(range_bound< TYPE > lower, range_bound< TYPE > upper)
Create a range.
Definition: range.hxx:206
static range< TYPE > from_string(std::string_view text)
Definition: range.hxx:391
bool operator==(range const &rhs) const
Definition: range.hxx:226