Mangrove
The C++ Object Document Mapper for MongoDB
macros.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 #define MANGROVE_PASTE_IMPL(s1, s2) s1##s2
20 #define MANGROVE_PASTE(s1, s2) MANGROVE_PASTE_IMPL(s1, s2)
21 
22 // Wrap a field name to create a corresponding NVP
23 #define MANGROVE_NVP(x) mangrove::make_nvp(&mangrove_wrap_base::x, #x)
24 
25 // Macro for creating custom field name
26 #define MANGROVE_CUSTOM_NVP(x, name) mangrove::make_nvp(&mangrove_wrap_base::x, name)
27 
28 // Creates serialize() function
29 #define MANGROVE_SERIALIZE_KEYS \
30  template <class Archive> \
31  void serialize(Archive& ar) { \
32  mangrove_serialize_recur<Archive, 0, \
33  std::tuple_size<decltype(mangrove_mapped_fields())>::value>(ar); \
34  } \
35  template <class Archive, size_t I, size_t N> \
36  std::enable_if_t<(I < N), void> mangrove_serialize_recur(Archive& ar) { \
37  auto nvp = std::get<I>(mangrove_mapped_fields()); \
38  ar(cereal::make_nvp(nvp.name, this->*(nvp.t))); \
39  mangrove_serialize_recur<Archive, I + 1, N>(ar); \
40  } \
41  \
42  template <class Archive, size_t I, size_t N> \
43  std::enable_if_t<(I == N), void> mangrove_serialize_recur(Archive&) { \
44  ; \
45  }
46 
47 // Register members and create serialize() function
48 #define MANGROVE_MAKE_KEYS(Base, ...) \
49  using mangrove_wrap_base = Base; \
50  constexpr static auto mangrove_mapped_fields() { \
51  return std::make_tuple(__VA_ARGS__); \
52  } \
53  MANGROVE_SERIALIZE_KEYS
54 
55 // If using the mangrove::model, then also register _id as a field.
56 #define MANGROVE_MAKE_KEYS_MODEL(Base, ...) MANGROVE_MAKE_KEYS(Base, MANGROVE_NVP(_id), __VA_ARGS__)
57 
58 #define MANGROVE_KEY(value) mangrove::hasCallIfFieldIsPresent<decltype(&value), &value>::call()
59 // convenience macro for accessing scalar elements of array fields in query builder.
60 #define MANGROVE_ELEM(value) MANGROVE_KEY(value).element()
61 
62 #define MANGROVE_KEY_BY_VALUE(value) \
63  mangrove::hasCallIfFieldIsPresent<decltype(value), value>::call()
64 
65 // MANGROVE_CHILD* macros, autogenerated to 100 levels (maximum BSON depth)
66 #include <mangrove/mangrove_child_autogen.hpp>
67 
68 #define MANGROVE_CHILD(type, ...) \
69  MANGROVE_PASTE(MANGROVE_CHILD, MANGROVE_PP_NARG(__VA_ARGS__))(type, __VA_ARGS__)
70 
71 #define MANGROVE_CHILD_ELEM(...) MANGROVE_CHILD(__VA_ARGS__).element()
72 
73 #include <mangrove/config/postlude.hpp>