4#if !defined(PQXX_HEADER_PRE)
5# error "Include libpqxx headers as <pqxx/header>, not <pqxx/header.hxx>."
26 template<
typename TYPE>
31 template<
typename TYPE>
54 throw argument_error{
"Got null value as an inclusive range bound."};
57 [[nodiscard]]
constexpr TYPE
const &
get() const & noexcept
64 noexcept(
noexcept(value < m_value))
66 return not(value < m_value);
71 noexcept(
noexcept(value < m_value))
73 return not(m_value < value);
93 throw argument_error{
"Got null value as an exclusive range bound."};
96 [[nodiscard]]
constexpr TYPE
const &
get() const & noexcept
103 noexcept(
noexcept(m_value < value))
105 return m_value < value;
110 noexcept(
noexcept(value < m_value))
112 return value < m_value;
143 std::declval<inclusive_bound<TYPE>
const &>()}) and
145 std::declval<exclusive_bound<TYPE>
const &>()})) =
default;
150 noexcept(
noexcept(*this->
value() == *rhs.value()))
154 rhs.is_limited() and (this->
is_inclusive() == rhs.is_inclusive()) and
155 (*this->
value() == *rhs.value()));
157 return not rhs.is_limited();
161 noexcept(
noexcept(*
this == rhs))
163 return not(*
this == rhs);
171 return not std::holds_alternative<no_bound>(m_bound);
177 return std::holds_alternative<inclusive_bound<TYPE>>(m_bound);
183 return std::holds_alternative<exclusive_bound<TYPE>>(m_bound);
190 [&
value](
auto const &bound)
noexcept(
noexcept(bound.extends_down_to(
191 value))) { return bound.extends_down_to(value); },
199 [&
value](
auto const &bound)
noexcept(
noexcept(
200 bound.extends_up_to(
value))) { return bound.extends_up_to(value); },
205 [[nodiscard]]
constexpr TYPE
const *
value() const & noexcept
208 [](
auto const &bound)
noexcept {
209 using bound_t = std::decay_t<
decltype(bound)>;
210 if constexpr (std::is_same_v<bound_t, no_bound>)
211 return static_cast<TYPE
const *
>(
nullptr);
253 m_lower{lower}, m_upper{upper}
259 "Range's lower bound (", *lower.
value(),
260 ") is greater than its upper bound (", *upper.
value(),
").")};
273 noexcept(this->
lower_bound() == rhs.lower_bound()) and
274 noexcept(this->
upper_bound() == rhs.upper_bound()) and
275 noexcept(this->
empty()))
277 return (this->
lower_bound() == rhs.lower_bound() and
278 this->upper_bound() == rhs.upper_bound()) or
279 (this->
empty() and rhs.empty());
283 noexcept(
noexcept(*
this == rhs))
285 return not(*
this == rhs);
302 constexpr bool empty() const noexcept(
303 noexcept(m_lower.is_exclusive()) and noexcept(m_lower.is_limited()) and
304 noexcept(*m_lower.value() < *m_upper.value()))
306 return (m_lower.is_exclusive() or m_upper.is_exclusive()) and
307 m_lower.is_limited() and m_upper.is_limited() and
308 not(*m_lower.value() < *m_upper.value());
312 constexpr bool contains(TYPE value)
const noexcept(
313 noexcept(m_lower.extends_down_to(value)) and
314 noexcept(m_upper.extends_up_to(value)))
316 return m_lower.extends_down_to(value) and m_upper.extends_up_to(value);
324 noexcept(
noexcept((*
this & other) == other))
326 return (*
this & other) == other;
352 else if (*other.
lower_bound().value() < *this->lower_bound().value())
364 else if (*other.
upper_bound().value() < *this->upper_bound().value())
378 return {lower, upper};
395 return {lower, upper};
406 [[nodiscard]]
static inline zview
419 char *here = begin + s_empty.copy(begin, std::size(s_empty));
429 (
static_cast<char>(value.
lower_bound().is_inclusive() ?
'[' :
'('));
432 if (lower !=
nullptr)
437 if (upper !=
nullptr)
439 if ((end - here) < 2)
442 static_cast<char>(value.
upper_bound().is_inclusive() ?
']' :
')');
450 if (std::size(
text) < 3)
452 bool left_inc{
false};
455 case '[': left_inc =
true;
break;
462 (std::size(
text) != std::size(s_empty)) or
463 (
text[1] !=
'm' and
text[1] !=
'M') or
464 (
text[2] !=
'p' and
text[2] !=
'P') or
465 (
text[3] !=
't' and
text[3] !=
'T') or
466 (
text[4] !=
'y' and
text[4] !=
'Y'))
476 std::size_t index{0};
478 static constexpr std::size_t last{1};
482 std::optional<TYPE> lower, upper;
484 auto const field_parser{
487 field_parser(index,
text, pos, lower, last);
488 field_parser(index,
text, pos, upper, last);
491 if (pos != std::size(
text))
493 char const closing{
text[pos - 1]};
494 if (closing !=
')' and closing !=
']')
496 bool const right_inc{closing ==
']'};
514 return {lower_bound, upper_bound};
517 [[nodiscard]]
static inline constexpr std::size_t
520 TYPE
const *lower{value.lower_bound().value()},
521 *upper{value.upper_bound().value()};
522 std::size_t
const lsz{
527 return std::size(s_empty) + 1;
529 return 1 + lsz + 1 + usz + 2;
533 static constexpr zview s_empty{
"empty"_zv};
534 static constexpr auto s_overrun{
"Not enough space in buffer for range."_zv};
537 static std::string err_bad_input(std::string_view text)
539 return internal::concat(
"Invalid range input: '", text,
"'");
An exclusive boundary value to a pqxx::range.
Definition range.hxx:83
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:109
constexpr exclusive_bound(TYPE const &value)
Definition range.hxx:90
constexpr TYPE const & get() const &noexcept
Definition range.hxx:96
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:102
An inclusive boundary value to a pqxx::range.
Definition range.hxx:44
constexpr inclusive_bound(TYPE const &value)
Definition range.hxx:51
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:63
constexpr TYPE const & get() const &noexcept
Definition range.hxx:57
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:70
A range boundary value.
Definition range.hxx:122
constexpr bool extends_up_to(TYPE const &value) const
Would this bound, as an upper bound, include value?
Definition range.hxx:196
constexpr range_bound(range_bound const &) noexcept(noexcept(inclusive_bound< TYPE >{ std::declval< inclusive_bound< TYPE > const & >()}) and noexcept(exclusive_bound< TYPE >{ std::declval< exclusive_bound< TYPE > const & >()}))=default
constexpr bool is_exclusive() const noexcept
Is this boundary an exclusive one?
Definition range.hxx:181
constexpr range_bound(inclusive_bound< TYPE > const &bound) noexcept(noexcept(inclusive_bound< TYPE >{bound}))
Definition range.hxx:131
constexpr bool is_limited() const noexcept
Is this a finite bound?
Definition range.hxx:169
constexpr TYPE const * value() const &noexcept
Return bound value, or nullptr if it's not limited.
Definition range.hxx:205
constexpr bool operator!=(range_bound const &rhs) const noexcept(noexcept(*this==rhs))
Definition range.hxx:160
constexpr bool extends_down_to(TYPE const &value) const
Would this bound, as a lower bound, include value?
Definition range.hxx:187
constexpr range_bound(no_bound) noexcept
Definition range.hxx:129
range_bound & operator=(range_bound const &)=default
constexpr bool operator==(range_bound const &rhs) const noexcept(noexcept(*this->value()== *rhs.value()))
Definition range.hxx:149
constexpr range_bound(exclusive_bound< TYPE > const &bound) noexcept(noexcept(exclusive_bound{bound}))
Definition range.hxx:136
constexpr bool is_inclusive() const noexcept
Is this boundary an inclusive one?
Definition range.hxx:175
range_bound & operator=(range_bound &&)=default
constexpr range_bound(range_bound &&)=default
A C++ equivalent to PostgreSQL's range types.
Definition range.hxx:241
constexpr range operator&(range const &other) const
Intersection of two ranges.
Definition range.hxx:343
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:272
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:312
constexpr bool contains(range< TYPE > const &other) const noexcept(noexcept((*this &other)==other))
Does this range encompass all of other?
Definition range.hxx:323
constexpr bool operator!=(range const &rhs) const noexcept(noexcept(*this==rhs))
Definition range.hxx:282
range(range const &)=default
range & operator=(range &&)=default
range & operator=(range const &)=default
constexpr range(range_bound< TYPE > lower, range_bound< TYPE > upper)
Create a range.
Definition range.hxx:252
constexpr range_bound< TYPE > const & upper_bound() const &noexcept
Definition range.hxx:335
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:302
constexpr range_bound< TYPE > const & lower_bound() const &noexcept
Definition range.hxx:330
constexpr range() noexcept(noexcept(exclusive_bound< TYPE >{TYPE{}}))
Create an empty range.
Definition range.hxx:267
Marker-type wrapper: zero-terminated std::string_view.
Definition zview.hxx:38
Invalid argument passed to libpqxx, similar to std::invalid_argument.
Definition except.hxx:266
Value conversion failed, e.g. when converting "Hello" to int.
Definition except.hxx:283
Could not convert value to string: not enough buffer space.
Definition except.hxx:313
Something is out of range, similar to std::out_of_range.
Definition except.hxx:326
std::string concat(TYPE... item)
Efficiently combine a bunch of items into one big string.
Definition concat.hxx:31
@ UTF8
Definition encoding_group.hxx:37
composite_field_parser< T > specialize_parse_composite_field(encoding_group enc)
Look up implementation of parse_composite_field for ENC.
Definition array-composite.hxx:274
auto ssize(T const &c)
Transitional: std::ssize(), or custom implementation if not available.
Definition util.hxx:555
The home of all libpqxx classes, functions, templates, etc.
Definition array.cxx:27
constexpr bool is_null(TYPE const &value) noexcept
Is value null?
Definition strconv.hxx:516
zview generic_to_buf(char *begin, char *end, TYPE const &value)
Implement string_traits<TYPE>::to_buf by calling into_buf.
Definition strconv.hxx:588
@ text
Definition types.hxx:71
An unlimited boundary value to a pqxx::range.
Definition range.hxx:25
constexpr bool extends_down_to(TYPE const &) const noexcept
Definition range.hxx:27
constexpr bool extends_up_to(TYPE const &) const noexcept
Definition range.hxx:32
Nullness traits describing a type which does not have a null value.
Definition strconv.hxx:114
Traits describing a type's "null value," if any.
Definition strconv.hxx:92
static constexpr std::size_t size_buffer(range< TYPE > const &value) noexcept
Definition range.hxx:518
static char * into_buf(char *begin, char *end, range< TYPE > const &value)
Definition range.hxx:413
static zview to_buf(char *begin, char *end, range< TYPE > const &value)
Definition range.hxx:407
static range< TYPE > from_string(std::string_view text)
Definition range.hxx:448
Traits class for use in string conversions.
Definition strconv.hxx:155
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, TYPE const &value)
Write value's string representation into buffer at begin.