Mangrove
The C++ Object Document Mapper for MongoDB
nvp.hpp
1 // Copyright 2016 MongoDB Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #pragma once
16 
17 #include <mangrove/config/prelude.hpp>
18 
19 #include <cstddef>
20 #include <stdexcept>
21 #include <tuple>
22 #include <type_traits>
23 
24 #include <bsoncxx/types.hpp>
25 
26 #include <mangrove/expression_syntax.hpp>
27 #include <mangrove/macros.hpp>
28 #include <mangrove/util.hpp>
29 
30 namespace mangrove {
31 MANGROVE_INLINE_NAMESPACE_BEGIN
32 
33 template <typename NvpT, typename T>
34 class nvp_base;
35 
37  constexpr current_date_t() {
38  }
39 };
40 constexpr current_date_t current_date;
41 
46 template <typename Base, typename T>
47 class nvp : public nvp_base<nvp<Base, T>, T> {
48  public:
49  using type = T;
50  // In case this field is wrapped in an optional, store the underlying type.
51  using no_opt_type = remove_optional_t<T>;
52 
58  constexpr nvp(T Base::*t, const char* name) : t(t), name(name) {
59  }
60 
64  constexpr update_expr<nvp<Base, T>, no_opt_type> operator=(const no_opt_type& val) const {
65  return {*this, val, "$set"};
66  }
67 
72  template <typename U = no_opt_type>
73  constexpr std::enable_if_t<is_date_v<U>, current_date_expr<nvp>> operator=(
74  const current_date_t&) const {
75  return {*this, true};
76  }
77 
82  template <typename U = no_opt_type>
83  constexpr std::enable_if_t<std::is_same<bsoncxx::types::b_timestamp, U>::value,
85  operator=(const current_date_t&) const {
86  return {*this, false};
87  }
88 
93  std::string get_name() const {
94  return name;
95  }
96 
97  std::string& append_name(std::string& s) const {
98  return s.append(name);
99  }
100 
101  T Base::*t;
102  const char* name;
103 };
104 
114 template <typename Base, typename T, typename Parent>
115 class nvp_child : public nvp_base<nvp_child<Base, T, Parent>, T> {
116  public:
117  using type = T;
118  // In case this field is wrapped in an optional, store the underlying type.
119  using no_opt_type = remove_optional_t<T>;
120 
121  constexpr nvp_child(T Base::*t, const char* name, const Parent& parent)
122  : t(t), name(name), parent(parent) {
123  }
124 
128  constexpr update_expr<nvp_child<Base, T, Parent>, T> operator=(const no_opt_type& val) const {
129  return {*this, val, "$set"};
130  }
131 
136  template <typename U = no_opt_type>
137  constexpr std::enable_if_t<is_date_v<U>, current_date_expr<nvp_child>> operator=(
138  const current_date_t&) const {
139  return {*this, true};
140  }
141 
146  template <typename U = no_opt_type>
147  constexpr std::enable_if_t<std::is_same<bsoncxx::types::b_timestamp, U>::value,
149  operator=(const current_date_t&) const {
150  return {*this, false};
151  }
152 
157  std::string get_name() const {
158  std::string s;
159  return append_name(s);
160  }
161 
166  std::string& append_name(std::string& s) const {
167  return parent.append_name(s).append(1, '.').append(name);
168  }
169 
170  T Base::*t;
171  const char* name;
172  const Parent& parent;
173 };
174 
175 template <typename NvpT>
177  : public nvp_base<array_element_nvp<NvpT>, iterable_value_t<typename NvpT::no_opt_type>> {
178  public:
179  using type = iterable_value_t<typename NvpT::no_opt_type>;
180  // In case this field is wrapped in an optional, store the underlying type.
181  using no_opt_type = remove_optional_t<type>;
182 
183  constexpr array_element_nvp(const NvpT& nvp, std::size_t i) : _nvp(nvp), _i(i) {
184  }
185 
190  const no_opt_type& val) const {
191  return {*this, val, "$set"};
192  }
193 
198  std::string get_name() const {
199  std::string s;
200  return append_name(s);
201  }
202 
208  std::string& append_name(std::string& s) const {
209  return _nvp.append_name(s).append(1, '.').append(std::to_string(_i));
210  }
211 
212  private:
213  const NvpT& _nvp;
214  const std::size_t _i;
215 };
216 
223 template <typename T>
224 class free_nvp : public nvp_base<free_nvp<T>, T> {
225  public:
226  // In case this corresponds to an optional type, store the underlying type.
227  using no_opt_type = remove_optional_t<T>;
228  using type = T;
229 
230  // TODO This shouldn't have a name, but it needs to work with Expressions when building queries.
231  std::string& append_name(std::string& s) const {
232  return s;
233  }
234 };
235 
236 template <typename NvpT>
237 struct is_free_nvp : public std::false_type {};
238 
239 template <typename T>
240 struct is_free_nvp<free_nvp<T>> : public std::true_type {};
241 
242 template <typename T>
243 constexpr bool is_free_nvp_v = is_free_nvp<T>::value;
244 
248 template <typename NvpT>
249 class dollar_operator_nvp : public nvp_base<dollar_operator_nvp<NvpT>, typename NvpT::type> {
250  public:
251  using type = iterable_value_t<typename NvpT::no_opt_type>;
252  // In case this field is wrapped in an optional, store the underlying type.
253  using no_opt_type = remove_optional_t<type>;
254 
255  constexpr dollar_operator_nvp(const NvpT& nvp) : _nvp(nvp) {
256  }
257 
262  const no_opt_type& val) const {
263  return {*this, val, "$set"};
264  }
265 
270  std::string get_name() const {
271  std::string s;
272  return append_name(s);
273  }
274 
279  std::string& append_name(std::string& s) const {
280  return _nvp.append_name(s).append(1, '.').append(1, '$');
281  }
282 
283  private:
284  const NvpT& _nvp;
285 };
286 
294 template <typename NvpT, typename T>
295 class nvp_base {
296  private:
297  // Type trait that checks if the given iterable class contains the same value type as either
298  // a) this nvp's type, or
299  // b) this nvp's value type, if this nvp is also an iterable.
300  template <typename Iterable, typename Default = void>
301  using enable_if_matching_iterable_t =
302  std::enable_if_t<is_iterable_not_string_v<Iterable> &&
303  std::is_convertible<iterable_value_t<Iterable>,
304  iterable_value_t<remove_optional_t<T>>>::value,
305  Default>;
306 
307  public:
308  using type = T;
309  // In case this field is wrapped in an optional, store the underlying type.
310  using no_opt_type = remove_optional_t<T>;
311  using child_base_type = iterable_value_t<no_opt_type>;
312 
323  template <typename U>
325  const nvp<iterable_value_t<no_opt_type>, U>& child) const {
326  return {child.t, child.name, *static_cast<const NvpT*>(this)};
327  }
328 
329  template <typename U = no_opt_type, typename = std::enable_if_t<is_iterable_not_string_v<U>>>
330  constexpr array_element_nvp<NvpT> operator[](std::size_t i) const {
331  return {*static_cast<const NvpT*>(this), i};
332  }
333 
340  constexpr sort_expr<NvpT> sort(bool ascending) const {
341  return {*static_cast<const NvpT*>(this), ascending};
342  }
343 
350  template <typename Iterable, typename = enable_if_matching_iterable_t<Iterable>>
351  constexpr comparison_expr<NvpT, Iterable> in(const Iterable& iter) const {
352  return {*static_cast<const NvpT*>(this), iter, "$in"};
353  }
354 
361  template <typename Iterable, typename = enable_if_matching_iterable_t<Iterable>>
362  constexpr comparison_expr<NvpT, Iterable> nin(const Iterable& iter) const {
363  return {*static_cast<const NvpT*>(this), iter, "$nin"};
364  }
365 
373  template <typename U = T, typename = std::enable_if_t<is_optional_v<U>>>
374  constexpr comparison_expr<NvpT, bool> exists(const bool& exists) const {
375  return {*static_cast<const NvpT*>(this), exists, "$exists"};
376  }
377 
385  template <typename U = no_opt_type, typename = std::enable_if_t<std::is_arithmetic<U>::value>>
386  constexpr mod_expr<NvpT> mod(const int& divisor, const int& remainder) const {
387  return {*static_cast<const NvpT*>(this), divisor, remainder};
388  }
389 
396  template <typename U = no_opt_type, typename = std::enable_if_t<is_string_v<U>>>
398  const char* regex, const char* options) const {
399  return {*static_cast<const NvpT*>(this), bsoncxx::types::b_regex(regex, options), "$regex"};
400  }
401 
402  /* Array Query operators */
403 
411  template <typename Iterable, typename = enable_if_matching_iterable_t<Iterable>,
412  typename U = no_opt_type, typename = std::enable_if_t<is_iterable_not_string_v<U>>>
413  constexpr comparison_expr<NvpT, Iterable> all(const Iterable& iter) const {
414  return {*static_cast<const NvpT*>(this), iter, "$all"};
415  }
416 
427  template <typename Expr, typename = std::enable_if_t<details::is_query_expression_v<Expr>>,
428  typename U = no_opt_type, typename = std::enable_if_t<is_iterable_v<U>>>
429  constexpr comparison_expr<NvpT, Expr> elem_match(const Expr& queries) const {
430  return {*static_cast<const NvpT*>(this), queries, "$elemMatch"};
431  }
432 
438  template <typename U = no_opt_type, typename = std::enable_if_t<is_iterable_not_string_v<U>>>
440  return {};
441  }
442 
448  template <typename U = no_opt_type, typename = std::enable_if_t<is_iterable_not_string_v<U>>>
449  constexpr comparison_expr<NvpT, std::int64_t> size(const std::int64_t& n) const {
450  return {*static_cast<const NvpT*>(this), n, "$size"};
451  }
452 
453  /* bitwise queries, enabled only for integral types. */
454 
461  template <typename U = no_opt_type,
462  typename = std::enable_if_t<std::is_integral<U>::value ||
463  std::is_same<U, bsoncxx::types::b_binary>::value>,
464  typename Mask,
465  typename = std::enable_if_t<std::is_integral<Mask>::value ||
466  std::is_same<Mask, bsoncxx::types::b_binary>::value>>
467  constexpr comparison_expr<NvpT, Mask> bits_all_set(const Mask& bitmask) const {
468  return {*static_cast<const NvpT*>(this), bitmask, "$bitsAllSet"};
469  }
470 
480  template <typename U = no_opt_type,
481  typename = std::enable_if_t<std::is_integral<U>::value ||
482  std::is_same<U, bsoncxx::types::b_binary>::value>,
483  typename... Args>
485  std::int64_t pos2,
486  Args... positions) const {
487  return {*static_cast<const NvpT*>(this), bit_positions_to_mask(pos1, pos2, positions...),
488  "$bitsAllSet"};
489  }
490 
497  template <typename U = no_opt_type,
498  typename = std::enable_if_t<std::is_integral<U>::value ||
499  std::is_same<U, bsoncxx::types::b_binary>::value>,
500  typename Mask,
501  typename = std::enable_if_t<std::is_integral<Mask>::value ||
502  std::is_same<Mask, bsoncxx::types::b_binary>::value>>
503  constexpr comparison_expr<NvpT, Mask> bits_any_set(const Mask& bitmask) const {
504  return {*static_cast<const NvpT*>(this), bitmask, "$bitsAnySet"};
505  }
506 
516  template <typename U = no_opt_type,
517  typename = std::enable_if_t<std::is_integral<U>::value ||
518  std::is_same<U, bsoncxx::types::b_binary>::value>,
519  typename... Args>
521  std::int64_t pos2,
522  Args... positions) const {
523  return {*static_cast<const NvpT*>(this), bit_positions_to_mask(pos1, pos2, positions...),
524  "$bitsAnySet"};
525  }
526 
534  template <typename U = no_opt_type,
535  typename = std::enable_if_t<std::is_integral<U>::value ||
536  std::is_same<U, bsoncxx::types::b_binary>::value>,
537  typename Mask,
538  typename = std::enable_if_t<std::is_integral<Mask>::value ||
539  std::is_same<Mask, bsoncxx::types::b_binary>::value>>
540  constexpr comparison_value_expr<NvpT, Mask> bits_all_clear(const Mask& bitmask) const {
541  return {*static_cast<const NvpT*>(this), bitmask, "$bitsAllClear"};
542  }
543 
553  template <typename U = no_opt_type,
554  typename = std::enable_if_t<std::is_integral<U>::value ||
555  std::is_same<U, bsoncxx::types::b_binary>::value>,
556  typename... Args>
558  std::int64_t pos2,
559  Args... positions) const {
560  return {*static_cast<const NvpT*>(this), bit_positions_to_mask(pos1, pos2, positions...),
561  "$bitsAllClear"};
562  }
563 
571  template <typename U = no_opt_type,
572  typename = std::enable_if_t<std::is_integral<U>::value ||
573  std::is_same<U, bsoncxx::types::b_binary>::value>,
574  typename Mask,
575  typename = std::enable_if_t<std::is_integral<Mask>::value ||
576  std::is_same<Mask, bsoncxx::types::b_binary>::value>>
577  constexpr comparison_expr<NvpT, Mask> bits_any_clear(const Mask& bitmask) const {
578  return {*static_cast<const NvpT*>(this), bitmask, "$bitsAnyClear"};
579  }
580 
590  template <typename U = no_opt_type,
591  typename = std::enable_if_t<std::is_integral<U>::value ||
592  std::is_same<U, bsoncxx::types::b_binary>::value>,
593  typename... Args>
595  std::int64_t pos2,
596  Args... positions) const {
597  return {*static_cast<const NvpT*>(this), bit_positions_to_mask(pos1, pos2, positions...),
598  "$bitsAnyClear"};
599  }
600 
601  constexpr update_expr<NvpT, no_opt_type> set_on_insert(const no_opt_type& val) const {
602  return {*static_cast<const NvpT*>(this), val, "$setOnInsert"};
603  }
604 
605  /* Update operators */
606 
611  template <typename U = T, typename = std::enable_if_t<is_optional_v<U>>>
612  constexpr unset_expr<NvpT> unset() const {
613  return {*static_cast<const NvpT*>(this)};
614  }
615 
622  constexpr update_expr<NvpT, no_opt_type> min(const no_opt_type& val) const {
623  return {*static_cast<const NvpT*>(this), val, "$min"};
624  }
625 
632  constexpr update_expr<NvpT, no_opt_type> max(const no_opt_type& val) const {
633  return {*static_cast<const NvpT*>(this), val, "$max"};
634  }
635 
636  /* Array update operators */
643  template <typename U = no_opt_type, typename = std::enable_if_t<is_iterable_not_string_v<U>>>
645  return {*static_cast<const NvpT*>(this)};
646  }
647 
654  template <typename U = no_opt_type, typename = std::enable_if_t<is_iterable_not_string_v<U>>>
655  constexpr update_value_expr<NvpT, int> pop(bool last) const {
656  return {*static_cast<const NvpT*>(this), last ? 1 : -1, "$pop"};
657  }
658 
665  template <typename U = no_opt_type, typename = std::enable_if_t<is_iterable_not_string_v<U>>>
667  const iterable_value_t<no_opt_type>& val) const {
668  return {*static_cast<const NvpT*>(this), val, "$pull"};
669  }
678  template <typename U = no_opt_type, typename = std::enable_if_t<is_iterable_not_string_v<U>>,
679  typename Expr>
680  constexpr std::enable_if_t<details::is_query_expression_v<Expr>, update_expr<NvpT, Expr>> pull(
681  const Expr& expr) const {
682  return {*static_cast<const NvpT*>(this), expr, "$pull"};
683  }
684 
691  template <typename U = no_opt_type, typename = std::enable_if_t<is_iterable_not_string_v<U>>,
692  typename Iterable, typename = enable_if_matching_iterable_t<Iterable>>
693  constexpr update_expr<NvpT, Iterable> pull_all(const Iterable& iter) const {
694  return {*static_cast<const NvpT*>(this), iter, "$pullAll"};
695  }
696 
703  template <typename U = no_opt_type, typename = std::enable_if_t<is_iterable_not_string_v<U>>>
705  const iterable_value_t<no_opt_type>& val) const {
706  return {*static_cast<const NvpT*>(this), val, false};
707  }
708 
715  template <typename U = no_opt_type, typename = std::enable_if_t<is_iterable_not_string_v<U>>,
716  typename Iterable, typename = enable_if_matching_iterable_t<Iterable>>
717  constexpr add_to_set_update_expr<NvpT, Iterable> add_to_set(const Iterable& iter) const {
718  return {*static_cast<const NvpT*>(this), iter, true};
719  }
720 
726  template <typename U = no_opt_type, typename = std::enable_if_t<is_iterable_not_string_v<U>>>
728  const iterable_value_t<no_opt_type>& val) const {
729  return {*static_cast<const NvpT*>(this), val, false};
730  }
731 
745  template <typename U = no_opt_type, typename = std::enable_if_t<is_iterable_not_string_v<U>>,
746  typename Iterable, typename = enable_if_matching_iterable_t<Iterable>,
747  typename Sort = int,
748  typename = std::enable_if_t<details::is_sort_expression_v<Sort> ||
749  std::is_same<int, Sort>::value>>
751  const Iterable& iter, bsoncxx::stdx::optional<std::int32_t> slice = bsoncxx::stdx::nullopt,
752  const bsoncxx::stdx::optional<Sort>& sort = bsoncxx::stdx::nullopt,
753  bsoncxx::stdx::optional<std::uint32_t> position = bsoncxx::stdx::nullopt) const {
754  return {*static_cast<const NvpT*>(this), iter, true, slice, sort, position};
755  }
756 };
757 
763 template <typename>
764 struct is_nvp : public std::false_type {};
765 
766 template <typename Base, typename T>
767 struct is_nvp<nvp<Base, T>> : public std::true_type {};
768 
769 template <typename Base, typename T, typename Parent>
770 struct is_nvp<nvp_child<Base, T, Parent>> : public std::true_type {};
771 
772 template <typename T>
773 struct is_nvp<free_nvp<T>> : public std::true_type {};
774 
775 template <typename NvpT>
776 struct is_nvp<array_element_nvp<NvpT>> : public std::true_type {};
777 
778 template <typename T>
779 constexpr bool is_nvp_v = is_nvp<T>::value;
780 
781 /* Create a name-value pair from a object member and its name */
782 template <typename Base, typename T>
783 nvp<Base, T> constexpr make_nvp(T Base::*t, const char* name) {
784  return nvp<Base, T>(t, name);
785 }
786 
791 template <typename Base, typename T, typename Parent>
792 nvp_child<Base, T, Parent> constexpr make_nvp_with_parent(const nvp<Base, T>& child,
793  const Parent& parent) {
794  return nvp_child<Base, T, Parent>(child.t, child.name, parent);
795 }
796 
801 // By default, if N>=M the index is out of bounds and hasField is false-y.
802 template <typename Base, typename T, size_t N, size_t M, bool = (N < M)>
803 struct hasField : public std::false_type {};
804 
805 // Nth member in the Base::fields tuple (i.e. the list of fields for which we
806 // have name-value pairs)
807 // Must have same type as the given argument.
808 template <typename Base, typename T, size_t N, size_t M>
810  : public std::is_same<T Base::*, decltype(std::get<N>(Base::mangrove_mapped_fields()).t)> {};
811 
817 // forward declarations for wrapbool
818 template <typename Base, typename T, size_t N, size_t M, T Base::*t>
819  constexpr std::enable_if_t < N<M && !hasField<Base, T, N, M>::value, bool> wrapbool();
820 
821 template <typename Base, typename T, size_t N, size_t M, T Base::*>
822 constexpr std::enable_if_t<N == M, bool> wrapbool();
823 
824 template <typename Base, typename T, size_t N, size_t M, T Base::*t>
825  constexpr std::enable_if_t < N<M && hasField<Base, T, N, M>::value, bool> wrapbool() {
826  if (std::get<N>(Base::mangrove_mapped_fields()).t == t) {
827  return true;
828  } else {
829  return wrapbool<Base, T, N + 1, M, t>();
830  }
831 }
832 
833 template <typename Base, typename T, size_t N, size_t M, T Base::*t>
834  constexpr std::enable_if_t < N<M && !hasField<Base, T, N, M>::value, bool> wrapbool() {
835  return wrapbool<Base, T, N + 1, M, t>();
836 }
837 
838 template <typename Base, typename T, size_t N, size_t M, T Base::*>
839 constexpr std::enable_if_t<N == M, bool> wrapbool() {
840  return false;
841 }
842 
849 // forward declarations for wrapimpl
850 template <typename Base, typename T, size_t N, size_t M>
851 constexpr std::enable_if_t<N == M, const nvp<Base, T>> wrapimpl(T Base::*t);
852 
853 template <typename Base, typename T, size_t N, size_t M>
854 constexpr std::enable_if_t<(N < M) && !hasField<Base, T, N, M>::value, const nvp<Base, T>> wrapimpl(
855  T Base::*t);
856 
857 // If Nth field has same type as T, check that it points to the same member.
858 // If not, check (N+1)th field.
859 template <typename Base, typename T, size_t N, size_t M>
860 constexpr std::enable_if_t<(N < M) && hasField<Base, T, N, M>::value, const nvp<Base, T>> wrapimpl(
861  T Base::*t) {
862  if (std::get<N>(Base::mangrove_mapped_fields()).t == t) {
863  return std::get<N>(Base::mangrove_mapped_fields());
864  } else {
865  return wrapimpl<Base, T, N + 1, M>(t);
866  }
867 }
868 
869 // If current field doesn't match the type of T, check (N+1)th field.
870 template <typename Base, typename T, size_t N, size_t M>
871 constexpr std::enable_if_t<(N < M) && !hasField<Base, T, N, M>::value, const nvp<Base, T>> wrapimpl(
872  T Base::*t) {
873  return wrapimpl<Base, T, N + 1, M>(t);
874 }
875 
876 // If N==M, we've gone past the last field, return nullptr.
877 template <typename Base, typename T, size_t N, size_t M>
878 constexpr std::enable_if_t<N == M, const nvp<Base, T>> wrapimpl(T Base::*) {
879  return nvp<Base, T>(nullptr, nullptr);
880 }
881 
889 template <typename Base, typename T>
890 constexpr const nvp<Base, T> wrap(T Base::*t) {
891  return wrapimpl<Base, T, 0, std::tuple_size<decltype(Base::mangrove_mapped_fields())>::value>(
892  t);
893 }
894 
900 template <typename T, T, typename = void>
901 struct hasCallIfFieldIsPresent {};
902 
903 template <typename Base, typename T, T Base::*ptr>
904 struct hasCallIfFieldIsPresent<
905  T Base::*, ptr,
906  std::enable_if_t<wrapbool<
907  Base, T, 0, std::tuple_size<decltype(Base::mangrove_mapped_fields())>::value, ptr>()>> {
908  static constexpr const nvp<Base, T> call() {
909  return wrap(ptr);
910  }
911 };
912 
913 MANGROVE_INLINE_NAMESPACE_END
914 } // namespace mangrove
915 
916 #include <mangrove/config/postlude.hpp>
Represents an array update epression that uses the $push operator.
Definition: expression_syntax.hpp:89
constexpr add_to_set_update_expr< NvpT, Iterable > add_to_set(const Iterable &iter) const
Creates an update expression with the $addToSet operator and the $each modifier, that adds a list of ...
Definition: nvp.hpp:717
std::string get_name() const
Returns the qualified name of this field in dot notation, i.e.
Definition: nvp.hpp:270
Creates an expression that uses the $currentDate operator.
Definition: expression_syntax.hpp:83
Definition: nvp.hpp:176
constexpr add_to_set_update_expr< NvpT, iterable_value_t< no_opt_type > > add_to_set(const iterable_value_t< no_opt_type > &val) const
Creates an update expression with the $addToSet operator, that adds a single value to an array...
Definition: nvp.hpp:704
constexpr std::enable_if_t< is_date_v< U >, current_date_expr< nvp > > operator=(const current_date_t &) const
Creates an expression that sets a date value to the current date.
Definition: nvp.hpp:73
constexpr update_expr< NvpT, no_opt_type > max(const no_opt_type &val) const
Creates an expression that uses the $max operator to only update a field if the new value is greater ...
Definition: nvp.hpp:632
An object that represents a name-value pair of a member in an object.
Definition: nvp.hpp:47
constexpr sort_expr< NvpT > sort(bool ascending) const
Creates a sort expression that sorts documents by this field.
Definition: nvp.hpp:340
constexpr std::enable_if_t< details::is_query_expression_v< Expr >, update_expr< NvpT, Expr > > pull(const Expr &expr) const
Creates an update expression with the $pull operator, that removes an element if it matches the given...
Definition: nvp.hpp:680
constexpr nvp_child< iterable_value_t< no_opt_type >, U, NvpT > operator->*(const nvp< iterable_value_t< no_opt_type >, U > &child) const
Chains two name-value pairs to access a sub-field, i.e.
Definition: nvp.hpp:324
constexpr comparison_value_expr< NvpT, std::int64_t > bits_any_set(std::int64_t pos1, std::int64_t pos2, Args...positions) const
Creates a query that uses the $bitsAnySet operator to check a series of bits, given as bit positions...
Definition: nvp.hpp:520
This class represents a query expression using the $mod operator, that checks the modulus of a certai...
Definition: expression_syntax.hpp:60
constexpr update_expr< NvpT, no_opt_type > min(const no_opt_type &val) const
Creates an expression that uses the $min operator to only update a field if the new value is lower th...
Definition: nvp.hpp:622
constexpr update_value_expr< NvpT, int > pop(bool last) const
Creates an update expression with the $pop operator.
Definition: nvp.hpp:655
constexpr mod_expr< NvpT > mod(const int &divisor, const int &remainder) const
Creates a mod_expr that represents a query with the $mod operator.
Definition: nvp.hpp:386
A CRTP base class that contains member functions for name-value pairs.
Definition: nvp.hpp:34
constexpr update_expr< nvp< Base, T >, no_opt_type > operator=(const no_opt_type &val) const
Creates an update expression that sets the field to the given value.
Definition: nvp.hpp:64
std::string get_name() const
Returns the qualified name of this field in dot notation, i.e.
Definition: nvp.hpp:198
constexpr comparison_expr< NvpT, Iterable > nin(const Iterable &iter) const
Creates an expression that checks whether the value of this field matches none of the values in the g...
Definition: nvp.hpp:362
constexpr update_expr< NvpT, iterable_value_t< no_opt_type > > pull(const iterable_value_t< no_opt_type > &val) const
Creates an update expression with the $pull operator, that removes an element if it matches the given...
Definition: nvp.hpp:666
std::string & append_name(std::string &s) const
Returns the qualified name of this field in dot notation, i.e.
Definition: nvp.hpp:208
constexpr comparison_expr< NvpT, Mask > bits_any_clear(const Mask &bitmask) const
Creates a query that uses the $bitsAnyClear operator to check a numerical field with a bitmask...
Definition: nvp.hpp:577
std::string & append_name(std::string &s) const
Returns the name of this field with the $ operator, i.e.
Definition: nvp.hpp:279
An expression that uses the $addToSet operator to add unique elements to an array.
Definition: expression_syntax.hpp:86
constexpr comparison_value_expr< NvpT, bsoncxx::types::b_regex > regex(const char *regex, const char *options) const
Creates a comparison expression that represents a query with a $regex operator.
Definition: nvp.hpp:397
constexpr comparison_value_expr< NvpT, std::int64_t > bits_any_clear(std::int64_t pos1, std::int64_t pos2, Args...positions) const
Creates a query that uses the $bitsAnyClear operator to check a series of bits, given as bit position...
Definition: nvp.hpp:594
Represents an expresion that uses the $unset operator.
Definition: expression_syntax.hpp:80
constexpr comparison_expr< NvpT, Mask > bits_any_set(const Mask &bitmask) const
Creates a query that uses the $bitsAnySet operator to check a numerical field with a bitmask...
Definition: nvp.hpp:503
constexpr unset_expr< NvpT > unset() const
Creates an expression that unsets the current field.
Definition: nvp.hpp:612
Represents an update operator that modifies a certain elements.
Definition: expression_syntax.hpp:74
Represents a field that does not have a name, i.e.
Definition: nvp.hpp:224
constexpr comparison_value_expr< NvpT, std::int64_t > bits_all_set(std::int64_t pos1, std::int64_t pos2, Args...positions) const
Creates a query that uses the $bitsAllSet operator to check a series of bits, given as bit positions...
Definition: nvp.hpp:484
Represents the $ operator applied to a field.
Definition: nvp.hpp:249
Definition: collection_wrapper.hpp:28
Class that represents a name-value pair for a field of an object that is a member of another object...
Definition: nvp.hpp:115
constexpr std::enable_if_t< is_date_v< U >, current_date_expr< nvp_child > > operator=(const current_date_t &) const
Creates an expression that sets a date value to the current date.
Definition: nvp.hpp:137
constexpr comparison_expr< NvpT, bool > exists(const bool &exists) const
Creates an expression that checks the existence of a certain field.
Definition: nvp.hpp:374
constexpr update_expr< NvpT, Iterable > pull_all(const Iterable &iter) const
Creates an update expression with the $pull operator, that removes an element if it matches the given...
Definition: nvp.hpp:693
std::string get_name() const
Returns the name of this field, in dot notation.
Definition: nvp.hpp:157
Represents a comparison expression as above, but stores a value instead of a reference.
Definition: expression_syntax.hpp:57
constexpr comparison_expr< NvpT, Expr > elem_match(const Expr &queries) const
Creates a query with the $elemMatch operator that finds elements in this field that match the given q...
Definition: nvp.hpp:429
A type trait struct that inherits from std::true_type if the given type parameter is a name-value pai...
Definition: nvp.hpp:764
constexpr push_update_expr< NvpT, iterable_value_t< no_opt_type > > push(const iterable_value_t< no_opt_type > &val) const
Creates an update epxression with the $push operator, that adds a single value to an array...
Definition: nvp.hpp:727
std::string & append_name(std::string &s) const
Returns the qualified name of this field in dot notation, i.e.
Definition: nvp.hpp:166
constexpr update_expr< dollar_operator_nvp< NvpT >, no_opt_type > operator=(const no_opt_type &val) const
Creates an update expression that sets the field to the given value.
Definition: nvp.hpp:261
constexpr comparison_value_expr< NvpT, Mask > bits_all_clear(const Mask &bitmask) const
Creates a query that uses the $bitsAllClear operator to check a numerical field with a bitmask...
Definition: nvp.hpp:540
constexpr std::enable_if_t< std::is_same< bsoncxx::types::b_timestamp, U >::value, current_date_expr< nvp > > operator=(const current_date_t &) const
Creates an expression that sets a date value to the current date.
Definition: nvp.hpp:85
constexpr std::enable_if_t< std::is_same< bsoncxx::types::b_timestamp, U >::value, current_date_expr< nvp_child > > operator=(const current_date_t &) const
Creates an expression that sets a date value to the current date.
Definition: nvp.hpp:149
constexpr comparison_expr< NvpT, Iterable > in(const Iterable &iter) const
Creates an expression that checks whether the value of this field matches any value in the given iter...
Definition: nvp.hpp:351
constexpr comparison_expr< NvpT, Iterable > all(const Iterable &iter) const
Creates a query with the $all operator that compares values in this field&#39;s array to values in anothe...
Definition: nvp.hpp:413
constexpr update_expr< nvp_child< Base, T, Parent >, T > operator=(const no_opt_type &val) const
Creates an update expression that sets the field to the given value.
Definition: nvp.hpp:128
Definition: expression_syntax.hpp:77
constexpr comparison_expr< NvpT, std::int64_t > size(const std::int64_t &n) const
Creates an array query expression with the $size operator.
Definition: nvp.hpp:449
An expression that represents a sorting order.
Definition: expression_syntax.hpp:48
Definition: nvp.hpp:36
constexpr push_update_expr< NvpT, Iterable, Sort > push(const Iterable &iter, bsoncxx::stdx::optional< std::int32_t > slice=bsoncxx::stdx::nullopt, const bsoncxx::stdx::optional< Sort > &sort=bsoncxx::stdx::nullopt, bsoncxx::stdx::optional< std::uint32_t > position=bsoncxx::stdx::nullopt) const
Creates an update epxression with the $push operator and the $each modifier, that adds a list of valu...
Definition: nvp.hpp:750
Represents a query expression with the syntax "key: {$op: value}".
Definition: expression_syntax.hpp:54
constexpr comparison_value_expr< NvpT, std::int64_t > bits_all_clear(std::int64_t pos1, std::int64_t pos2, Args...positions) const
Creates a query that uses the $bitsAllClear operator to check a series of bits, given as bit position...
Definition: nvp.hpp:557
constexpr dollar_operator_nvp< NvpT > first_match() const
Returns a name-value pair with the $ operator appended to it.
Definition: nvp.hpp:644
constexpr update_expr< array_element_nvp< NvpT >, no_opt_type > operator=(const no_opt_type &val) const
Creates an update expression that sets the field to the given value.
Definition: nvp.hpp:189
constexpr nvp(T Base::*t, const char *name)
Create a name-value pair from a member pointer and a name.
Definition: nvp.hpp:58
std::string get_name() const
Returns the name of this field.
Definition: nvp.hpp:93
Definition: nvp.hpp:237
constexpr free_nvp< iterable_value_t< no_opt_type > > element() const
Constructs a nameless name-value-pair that corresponds to an element in a scalar array, if this field is an array.
Definition: nvp.hpp:439
constexpr comparison_expr< NvpT, Mask > bits_all_set(const Mask &bitmask) const
Creates a query that uses the $bitsAllSet operator to check a numerical field with a bitmask...
Definition: nvp.hpp:467