4 #if !defined(PQXX_HEADER_PRE)
5 # error "Include libpqxx headers as <pqxx/header>, not <pqxx/header.hxx>."
11 #include "pqxx/internal/array-composite.hxx"
12 #include "pqxx/internal/concat.hxx"
25 template<
typename TYPE>
30 template<
typename TYPE>
53 throw argument_error{
"Got null value as an inclusive range bound."};
56 [[nodiscard]] constexpr TYPE
const &
get()
const &noexcept {
return m_value; }
60 noexcept(noexcept(value < m_value))
62 return not(value < m_value);
67 noexcept(noexcept(value < m_value))
69 return not(m_value < value);
89 throw argument_error{
"Got null value as an exclusive range bound."};
92 [[nodiscard]] constexpr TYPE
const &
get()
const &noexcept {
return m_value; }
96 noexcept(noexcept(m_value < value))
98 return m_value < value;
103 noexcept(noexcept(value < m_value))
105 return value < m_value;
135 noexcept(inclusive_bound<TYPE>{
136 std::declval<inclusive_bound<TYPE>
const &>()})
137 and noexcept(exclusive_bound<TYPE>{
138 std::declval<exclusive_bound<TYPE>
const &>()})) =
default;
143 noexcept(noexcept(*this->
value() == *rhs.value()))
147 rhs.is_limited() and (this->
is_inclusive() == rhs.is_inclusive()) and
148 (*this->
value() == *rhs.value()));
150 return not rhs.is_limited();
154 noexcept(noexcept(*
this == rhs))
156 return not(*
this == rhs);
164 return not std::holds_alternative<no_bound>(m_bound);
170 return std::holds_alternative<inclusive_bound<TYPE>>(m_bound);
176 return std::holds_alternative<exclusive_bound<TYPE>>(m_bound);
183 [&value](
auto const &bound) noexcept(noexcept(bound.extends_down_to(
184 value))) {
return bound.extends_down_to(value); },
192 [&value](
auto const &bound) noexcept(noexcept(
193 bound.extends_up_to(value))) {
return bound.extends_up_to(value); },
198 [[nodiscard]] constexpr TYPE
const *
value() const &noexcept
201 [](
auto const &bound) noexcept {
202 using bound_t = std::decay_t<decltype(bound)>;
203 if constexpr (std::is_same_v<bound_t, no_bound>)
204 return static_cast<TYPE
const *
>(
nullptr);
246 m_lower{lower}, m_upper{upper}
249 lower.is_limited() and upper.is_limited() and
250 (*upper.value() < *lower.value()))
251 throw range_error{internal::concat(
252 "Range's lower bound (", *lower.value(),
253 ") is greater than its upper bound (", *upper.value(),
").")};
262 m_upper{exclusive_bound<TYPE>{TYPE{}}}
266 noexcept(noexcept(this->lower_bound() == rhs.lower_bound()) and noexcept(
267 this->upper_bound() == rhs.upper_bound()) and noexcept(this->empty()))
269 return (this->lower_bound() == rhs.lower_bound() and
270 this->upper_bound() == rhs.upper_bound()) or
271 (this->empty() and rhs.empty());
275 noexcept(noexcept(*
this == rhs))
277 return not(*
this == rhs);
315 noexcept(noexcept((*
this & other) == other))
317 return (*
this & other) == other;
340 lower = this->lower_bound();
341 else if (*this->lower_bound().value() < *other.
lower_bound().value())
343 else if (*other.
lower_bound().value() < *this->lower_bound().value())
344 lower = this->lower_bound();
345 else if (this->lower_bound().is_exclusive())
346 lower = this->lower_bound();
354 upper = this->upper_bound();
355 else if (*other.
upper_bound().value() < *this->upper_bound().value())
358 upper = this->upper_bound();
359 else if (this->upper_bound().is_exclusive())
360 upper = this->upper_bound();
365 lower.is_limited() and upper.is_limited() and
366 (*upper.value() < *lower.value()))
369 return {lower, upper};
376 if (lower_bound().is_inclusive())
386 return {lower, upper};
397 [[nodiscard]]
static inline zview
410 char *here = begin + s_empty.copy(begin, std::size(s_empty));
420 (
static_cast<char>(value.
lower_bound().is_inclusive() ?
'[' :
'('));
423 if (lower !=
nullptr)
428 if (upper !=
nullptr)
430 if ((end - here) < 2)
433 static_cast<char>(value.
upper_bound().is_inclusive() ?
']' :
')');
441 if (std::size(text) < 3)
443 bool left_inc{
false};
446 case '[': left_inc =
true;
break;
453 (std::size(text) != std::size(s_empty)) or
454 (text[1] !=
'm' and text[1] !=
'M') or
455 (text[2] !=
'p' and text[2] !=
'P') or
456 (text[3] !=
't' and text[3] !=
'T') or
457 (text[4] !=
'y' and text[4] !=
'Y'))
467 std::size_t index{0};
469 static constexpr std::size_t last{1};
473 std::optional<TYPE> lower, upper;
475 auto const field_parser{
476 pqxx::internal::specialize_parse_composite_field<std::optional<TYPE>>(
477 pqxx::internal::encoding_group::UTF8)};
478 field_parser(index, text, pos, lower, last);
479 field_parser(index, text, pos, upper, last);
482 if (pos != std::size(text))
484 char const closing{text[pos - 1]};
485 if (closing !=
')' and closing !=
']')
487 bool const right_inc{closing ==
']'};
505 return {lower_bound, upper_bound};
508 [[nodiscard]]
static inline constexpr std::size_t
511 TYPE
const *lower{
value.lower_bound().value()},
512 *upper{
value.upper_bound().value()};
513 std::size_t
const lsz{
518 return std::size(s_empty) + 1;
520 return 1 + lsz + 1 + usz + 2;
524 static constexpr
zview s_empty{
"empty"_zv};
525 static constexpr
auto s_overrun{
"Not enough space in buffer for range."_zv};
528 static std::string err_bad_input(std::string_view text)
530 return internal::concat(
"Invalid range input: '", text,
"'");
constexpr bool is_inclusive() const noexcept
Is this boundary an inclusive one?
Definition: range.hxx:168
Could not convert value to string: not enough buffer space.
Definition: except.hxx:312
constexpr bool is_limited() const noexcept
Is this a finite bound?
Definition: range.hxx:162
constexpr range_bound(no_bound) noexcept
Definition: range.hxx:122
constexpr bool extends_up_to(TYPE const &value) const noexcept(noexcept(value< m_value))
Would this bound, as an upper bound, include value?
Definition: range.hxx:102
Traits class for use in string conversions.
Definition: strconv.hxx:154
constexpr range_bound< TYPE > const & upper_bound() const &noexcept
Definition: range.hxx:326
An inclusive boundary value to a pqxx::range.
Definition: range.hxx:42
static constexpr std::size_t size_buffer(range< TYPE > const &value) noexcept
Definition: range.hxx:509
An exclusive boundary value to a pqxx::range.
Definition: range.hxx:78
constexpr range() noexcept(noexcept(exclusive_bound< TYPE >{TYPE{}}))
Create an empty range.
Definition: range.hxx:260
constexpr bool extends_down_to(TYPE const &value) const noexcept(noexcept(m_value< value))
Would this bound, as a lower bound, include value?
Definition: range.hxx:95
constexpr bool operator==(range_bound const &rhs) const noexcept(noexcept(*this->value()==*rhs.value()))
Definition: range.hxx:142
Invalid argument passed to libpqxx, similar to std::invalid_argument.
Definition: except.hxx:265
range_bound & operator=(range_bound const &)=default
The home of all libpqxx classes, functions, templates, etc.
Definition: array.hxx:32
An unlimited boundary value to a pqxx::range.
Definition: range.hxx:23
constexpr range_bound(exclusive_bound< TYPE > const &bound) noexcept( noexcept(exclusive_bound{bound}))
Definition: range.hxx:129
constexpr bool empty() const noexcept(noexcept(m_lower.is_exclusive()) and noexcept( m_lower.is_limited()) and noexcept(*m_lower.value()< *m_upper.value()))
Is this range clearly empty?
Definition: range.hxx:294
static std::size_t size_buffer(TYPE const &value) noexcept
Estimate how much buffer space is needed to represent value.
static char * into_buf(char *begin, char *end, range< TYPE > const &value)
Definition: range.hxx:404
Traits describing a type's "null value," if any.
Definition: strconv.hxx:92
constexpr bool extends_up_to(TYPE const &value) const noexcept(noexcept(value< m_value))
Would this bound, as an upper bound, include value?
Definition: range.hxx:66
Value conversion failed, e.g. when converting "Hello" to int.
Definition: except.hxx:282
constexpr bool extends_down_to(TYPE const &value) const
Would this bound, as a lower bound, include value?
Definition: range.hxx:180
A range boundary value.
Definition: range.hxx:114
constexpr range_bound< TYPE > const & lower_bound() const &noexcept
Definition: range.hxx:321
Marker-type wrapper: zero-terminated std::string_view.
Definition: zview.hxx:37
zview generic_to_buf(char *begin, char *end, TYPE const &value)
Implement string_traits::to_buf by calling into_buf.
Definition: strconv.hxx:590
constexpr range_bound(inclusive_bound< TYPE > const &bound) noexcept( noexcept(inclusive_bound< TYPE >{bound}))
Definition: range.hxx:124
constexpr bool operator==(range const &rhs) const noexcept(noexcept(this->lower_bound()==rhs.lower_bound()) and noexcept( this->upper_bound()==rhs.upper_bound()) and noexcept(this->empty()))
Definition: range.hxx:265
static char * into_buf(char *begin, char *end, TYPE const &value)
Write value's string representation into buffer at begin.
constexpr range operator&(range const &other) const
Intersection of two ranges.
Definition: range.hxx:334
constexpr bool operator!=(range_bound const &rhs) const noexcept(noexcept(*this==rhs))
Definition: range.hxx:153
constexpr bool operator!=(range const &rhs) const noexcept(noexcept(*this==rhs))
Definition: range.hxx:274
auto ssize(T const &c)
Transitional: std::ssize(), or custom implementation if not available.
Definition: util.hxx:453
constexpr bool contains(range< TYPE > const &other) const noexcept(noexcept((*this &other)==other))
Does this range encompass all of other?
Definition: range.hxx:314
constexpr bool extends_down_to(TYPE const &) const noexcept
Definition: range.hxx:26
constexpr inclusive_bound(TYPE const &value)
Definition: range.hxx:50
constexpr bool is_exclusive() const noexcept
Is this boundary an exclusive one?
Definition: range.hxx:174
A C++ equivalent to PostgreSQL's range types.
Definition: range.hxx:233
static zview to_buf(char *begin, char *end, range< TYPE > const &value)
Definition: range.hxx:398
static range< TYPE > from_string(std::string_view text)
Definition: range.hxx:439
constexpr exclusive_bound(TYPE const &value)
Definition: range.hxx:86
constexpr bool extends_down_to(TYPE const &value) const noexcept(noexcept(value< m_value))
Would this bound, as a lower bound, include value?
Definition: range.hxx:59
constexpr bool is_null(TYPE const &value) noexcept
Is value null?
Definition: strconv.hxx:518
constexpr bool extends_up_to(TYPE const &value) const
Would this bound, as an upper bound, include value?
Definition: range.hxx:189
constexpr TYPE const * value() const &noexcept
Return bound value, or nullptr if it's not limited.
Definition: range.hxx:198
constexpr bool extends_up_to(TYPE const &) const noexcept
Definition: range.hxx:31
constexpr range(range_bound< TYPE > lower, range_bound< TYPE > upper)
Create a range.
Definition: range.hxx:245
constexpr bool contains(TYPE value) const noexcept(noexcept( m_lower.extends_down_to(value)) and noexcept(m_upper.extends_up_to(value)))
Does this range encompass value?
Definition: range.hxx:304
Nullness traits describing a type which does not have a null value.
Definition: strconv.hxx:114