core.hpp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698
  1. // Copyright 2014 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. #pragma once
  15. #include <memory>
  16. #include <stdexcept>
  17. #include <type_traits>
  18. #include <bsoncxx/array/value.hpp>
  19. #include <bsoncxx/array/view.hpp>
  20. #include <bsoncxx/document/value.hpp>
  21. #include <bsoncxx/document/view.hpp>
  22. #include <bsoncxx/stdx/string_view.hpp>
  23. #include <bsoncxx/types.hpp>
  24. #include <bsoncxx/config/prelude.hpp>
  25. namespace bsoncxx {
  26. BSONCXX_INLINE_NAMESPACE_BEGIN
  27. namespace builder {
  28. ///
  29. /// A low-level interface for constructing BSON documents and arrays.
  30. ///
  31. /// @remark
  32. /// Generally it is recommended to use the classes in builder::basic or builder::stream instead of
  33. /// using this class directly. However, developers who wish to write their own abstractions may
  34. /// find this class useful.
  35. ///
  36. class BSONCXX_API core {
  37. public:
  38. class BSONCXX_PRIVATE impl;
  39. ///
  40. /// Constructs an empty BSON datum.
  41. ///
  42. /// @param is_array
  43. /// True if the top-level BSON datum should be an array.
  44. ///
  45. explicit core(bool is_array);
  46. core(core&& rhs) noexcept;
  47. core& operator=(core&& rhs) noexcept;
  48. ~core();
  49. ///
  50. /// Appends a key passed as a non-owning stdx::string_view.
  51. ///
  52. /// @remark
  53. /// Use key_owned() unless you know what you are doing.
  54. ///
  55. /// @warning
  56. /// The caller must ensure that the lifetime of the backing string extends until the next
  57. /// value is appended.
  58. ///
  59. /// @param key
  60. /// A null-terminated array of characters.
  61. ///
  62. /// @return
  63. /// A reference to the object on which this member function is being called. This facilitates
  64. /// method chaining.
  65. ///
  66. /// @throws bsoncxx::exception if the current BSON datum is an array or if the previous value
  67. /// appended to the builder was also a key.
  68. ///
  69. core& key_view(stdx::string_view key);
  70. ///
  71. /// Appends a key passed as an STL string. Transfers ownership of the key to this class.
  72. ///
  73. /// @param key
  74. /// A string key.
  75. ///
  76. /// @return
  77. /// A reference to the object on which this member function is being called. This facilitates
  78. /// method chaining.
  79. ///
  80. /// @throws bsoncxx::exception if the current BSON datum is an array or if the previous value
  81. /// appended to the builder was a key.
  82. ///
  83. core& key_owned(std::string key);
  84. ///
  85. /// Opens a sub-document within this BSON datum.
  86. ///
  87. /// @return
  88. /// A reference to the object on which this member function is being called. This facilitates
  89. /// method chaining.
  90. ///
  91. /// @throws
  92. /// bsoncxx::exception if the current BSON datum is a document that is waiting for a key to be
  93. /// appended to start a new key/value pair.
  94. ///
  95. core& open_document();
  96. ///
  97. /// Opens a sub-array within this BSON datum.
  98. ///
  99. /// @return
  100. /// A reference to the object on which this member function is being called. This facilitates
  101. /// method chaining.
  102. ///
  103. /// @throws
  104. /// bsoncxx::exception if the current BSON datum is a document that is waiting for a key to be
  105. /// appended to start a new key/value pair.
  106. ///
  107. core& open_array();
  108. ///
  109. /// Closes the current sub-document within this BSON datum.
  110. ///
  111. /// @return
  112. /// A reference to the object on which this member function is being called. This facilitates
  113. /// method chaining.
  114. ///
  115. /// @throws bsoncxx::exception if the current BSON datum is not an open sub-document.
  116. ///
  117. core& close_document();
  118. ///
  119. /// Closes the current sub-array within this BSON datum.
  120. ///
  121. /// @return
  122. /// A reference to the object on which this member function is being called. This facilitates
  123. /// method chaining.
  124. ///
  125. /// @throws bsoncxx::exception if the current BSON datum is not an open sub-array.
  126. ///
  127. core& close_array();
  128. ///
  129. /// Appends the keys from a BSON document into this BSON datum.
  130. ///
  131. /// @note
  132. /// If this BSON datum is a document, the original keys from `view` are kept. Otherwise (if
  133. /// this BSON datum is an array), the original keys from `view` are discarded.
  134. ///
  135. /// @note
  136. /// This can be used with an array::view as well by converting it to a document::view first.
  137. ///
  138. /// @return
  139. /// A reference to the object on which this member function is being called. This facilitates
  140. /// method chaining.
  141. ///
  142. /// @throws
  143. /// bsoncxx::exception if one of the keys fails to append.
  144. ///
  145. core& concatenate(const document::view& view);
  146. ///
  147. /// Appends a BSON double.
  148. ///
  149. /// @return
  150. /// A reference to the object on which this member function is being called. This facilitates
  151. /// method chaining.
  152. ///
  153. /// @throws
  154. /// bsoncxx::exception if the current BSON datum is a document that is waiting for a key to be
  155. /// appended to start a new key/value pair.
  156. /// bsoncxx::exception if the double fails to append.
  157. ///
  158. core& append(const types::b_double& value);
  159. ///
  160. /// Append a BSON UTF-8 string.
  161. ///
  162. /// @return
  163. /// A reference to the object on which this member function is being called. This facilitates
  164. /// method chaining.
  165. ///
  166. /// @throws
  167. /// bsoncxx::exception if the current BSON datum is a document that is waiting for a key to be
  168. /// appended to start a new key/value pair.
  169. /// bsoncxx::exception if the utf8 fails to append.
  170. ///
  171. core& append(const types::b_utf8& value);
  172. ///
  173. /// Appends a BSON document.
  174. ///
  175. /// @return
  176. /// A reference to the object on which this member function is being called. This facilitates
  177. /// method chaining.
  178. ///
  179. /// @throws
  180. /// bsoncxx::exception if the current BSON datum is a document that is waiting for a key to be
  181. /// appended to start a new key/value pair.
  182. /// bsoncxx::exception if the document fails to append.
  183. ///
  184. core& append(const types::b_document& value);
  185. ///
  186. /// Appends a BSON array.
  187. ///
  188. /// @return
  189. /// A reference to the object on which this member function is being called. This facilitates
  190. /// method chaining.
  191. ///
  192. /// @throws
  193. /// bsoncxx::exception if the current BSON datum is a document that is waiting for a key to be
  194. /// appended to start a new key/value pair.
  195. /// bsoncxx::exception if the array fails to append.
  196. ///
  197. core& append(const types::b_array& value);
  198. ///
  199. /// Appends a BSON binary datum.
  200. ///
  201. /// @return
  202. /// A reference to the object on which this member function is being called. This facilitates
  203. /// method chaining.
  204. ///
  205. /// @throws
  206. /// bsoncxx::exception if the current BSON datum is a document that is waiting for a key to be
  207. /// appended to start a new key/value pair.
  208. /// bsoncxx::exception if the binary fails to append.
  209. ///
  210. core& append(const types::b_binary& value);
  211. ///
  212. /// Appends a BSON undefined.
  213. ///
  214. /// @return
  215. /// A reference to the object on which this member function is being called. This facilitates
  216. /// method chaining.
  217. ///
  218. /// @throws
  219. /// bsoncxx::exception if the current BSON datum is a document that is waiting for a key to be
  220. /// appended to start a new key/value pair.
  221. /// bsoncxx::exception if undefined fails to append.
  222. ///
  223. core& append(const types::b_undefined& value);
  224. ///
  225. /// Appends a BSON ObjectId.
  226. ///
  227. /// @return
  228. /// A reference to the object on which this member function is being called. This facilitates
  229. /// method chaining.
  230. ///
  231. /// @throws
  232. /// bsoncxx::exception if the current BSON datum is a document that is waiting for a key to be
  233. /// appended to start a new key/value pair.
  234. /// bsoncxx::exception if the ObjectId fails to append.
  235. ///
  236. core& append(const types::b_oid& value);
  237. ///
  238. /// Appends a BSON boolean.
  239. ///
  240. /// @return
  241. /// A reference to the object on which this member function is being called. This facilitates
  242. /// method chaining.
  243. ///
  244. /// @throws
  245. /// bsoncxx::exception if the current BSON datum is a document that is waiting for a key to be
  246. /// appended to start a new key/value pair.
  247. /// bsoncxx::exception if the boolean fails to append.
  248. ///
  249. core& append(const types::b_bool& value);
  250. ///
  251. /// Appends a BSON date.
  252. ///
  253. /// @return
  254. /// A reference to the object on which this member function is being called. This facilitates
  255. /// method chaining.
  256. ///
  257. /// @throws
  258. /// bsoncxx::exception if the current BSON datum is a document that is waiting for a key to be
  259. /// appended to start a new key/value pair.
  260. /// bsoncxx::exception if the date fails to append.
  261. ///
  262. core& append(const types::b_date& value);
  263. ///
  264. /// Appends a BSON null.
  265. ///
  266. /// @return
  267. /// A reference to the object on which this member function is being called. This facilitates
  268. /// method chaining.
  269. ///
  270. /// @throws
  271. /// bsoncxx::exception if the current BSON datum is a document that is waiting for a key to be
  272. /// appended to start a new key/value pair.
  273. /// bsoncxx::exception if null fails to append.
  274. ///
  275. core& append(const types::b_null& value);
  276. ///
  277. /// Appends a BSON regex.
  278. ///
  279. /// @return
  280. /// A reference to the object on which this member function is being called. This facilitates
  281. /// method chaining.
  282. ///
  283. /// @throws
  284. /// bsoncxx::exception if the current BSON datum is a document that is waiting for a key to be
  285. /// appended to start a new key/value pair.
  286. /// bsoncxx::exception if the regex fails to append.
  287. ///
  288. core& append(const types::b_regex& value);
  289. ///
  290. /// Appends a BSON DBPointer.
  291. ///
  292. /// @return
  293. /// A reference to the object on which this member function is being called. This facilitates
  294. /// method chaining.
  295. ///
  296. /// @throws
  297. /// bsoncxx::exception if the current BSON datum is a document that is waiting for a key to be
  298. /// appended to start a new key/value pair.
  299. /// bsoncxx::exception if the DBPointer fails to append.
  300. ///
  301. core& append(const types::b_dbpointer& value);
  302. ///
  303. /// Appends a BSON JavaScript code.
  304. ///
  305. /// @return
  306. /// A reference to the object on which this member function is being called. This facilitates
  307. /// method chaining.
  308. ///
  309. /// @throws
  310. /// bsoncxx::exception if the current BSON datum is a document that is waiting for a key to be
  311. /// appended to start a new key/value pair.
  312. /// bsoncxx::exception if the JavaScript code fails to append.
  313. ///
  314. core& append(const types::b_code& value);
  315. ///
  316. /// Appends a BSON symbol.
  317. ///
  318. /// @return
  319. /// A reference to the object on which this member function is being called. This facilitates
  320. /// method chaining.
  321. ///
  322. /// @throws
  323. /// bsoncxx::exception if the current BSON datum is a document that is waiting for a key to be
  324. /// appended to start a new key/value pair.
  325. /// bsoncxx::exception if the symbol fails to append.
  326. ///
  327. core& append(const types::b_symbol& value);
  328. ///
  329. /// Appends a BSON JavaScript code with scope.
  330. ///
  331. /// @return
  332. /// A reference to the object on which this member function is being called. This facilitates
  333. /// method chaining.
  334. ///
  335. /// @throws
  336. /// bsoncxx::exception if the current BSON datum is a document that is waiting for a key to be
  337. /// appended to start a new key/value pair.
  338. /// bsoncxx::exception if the JavaScript code with scope fails to append.
  339. ///
  340. core& append(const types::b_codewscope& value);
  341. ///
  342. /// Appends a BSON 32-bit signed integer.
  343. ///
  344. /// @return
  345. /// A reference to the object on which this member function is being called. This facilitates
  346. /// method chaining.
  347. ///
  348. /// @throws
  349. /// bsoncxx::exception if the current BSON datum is a document that is waiting for a key to be
  350. /// appended to start a new key/value pair.
  351. /// bsoncxx::exception if the 32-bit signed integer fails to append.
  352. ///
  353. core& append(const types::b_int32& value);
  354. ///
  355. /// Appends a BSON replication timestamp.
  356. ///
  357. /// @return
  358. /// A reference to the object on which this member function is being called. This facilitates
  359. /// method chaining.
  360. ///
  361. /// @throws
  362. /// bsoncxx::exception if the current BSON datum is a document that is waiting for a key to be
  363. /// appended to start a new key/value pair.
  364. /// bsoncxx::exception if the timestamp fails to append.
  365. ///
  366. core& append(const types::b_timestamp& value);
  367. ///
  368. /// Appends a BSON 64-bit signed integer.
  369. ///
  370. /// @return
  371. /// A reference to the object on which this member function is being called. This facilitates
  372. /// method chaining.
  373. ///
  374. /// @throws
  375. /// bsoncxx::exception if the current BSON datum is a document that is waiting for a key to be
  376. /// appended to start a new key/value pair.
  377. /// bsoncxx::exception if the 64-bit signed integer fails to append.
  378. ///
  379. core& append(const types::b_int64& value);
  380. ///
  381. /// Appends a BSON Decimal128.
  382. ///
  383. /// @return
  384. /// A reference to the object on which this member function is being called. This facilitates
  385. /// method chaining.
  386. ///
  387. /// @throws
  388. /// bsoncxx::exception if the current BSON datum is a document that is waiting for a key to be
  389. /// appended to start a new key/value pair.
  390. /// bsoncxx::exception if the Decimal128 fails to append.
  391. ///
  392. core& append(const types::b_decimal128& value);
  393. ///
  394. /// Appends a BSON min-key.
  395. ///
  396. /// @return
  397. /// A reference to the object on which this member function is being called. This facilitates
  398. /// method chaining.
  399. ///
  400. /// @throws
  401. /// bsoncxx::exception if the current BSON datum is a document that is waiting for a key to be
  402. /// appended to start a new key/value pair.
  403. /// bsoncxx::exception if the min-key fails to append.
  404. ///
  405. core& append(const types::b_minkey& value);
  406. ///
  407. /// Appends a BSON max-key.
  408. ///
  409. /// @return
  410. /// A reference to the object on which this member function is being called. This facilitates
  411. /// method chaining.
  412. ///
  413. /// @throws
  414. /// bsoncxx::exception if the current BSON datum is a document that is waiting for a key to be
  415. /// appended to start a new key/value pair.
  416. /// bsoncxx::exception if the max-key fails to append.
  417. ///
  418. core& append(const types::b_maxkey& value);
  419. ///
  420. /// Appends a BSON variant value.
  421. ///
  422. /// @return
  423. /// A reference to the object on which this member function is being called. This facilitates
  424. /// method chaining.
  425. ///
  426. /// @throws
  427. /// bsoncxx::exception if the current BSON datum is a document that is waiting for a key to be
  428. /// appended to start a new key/value pair.
  429. ///
  430. core& append(const types::bson_value::view& value);
  431. ///
  432. /// Appends an STL string as a BSON UTF-8 string.
  433. ///
  434. /// @return
  435. /// A reference to the object on which this member function is being called. This facilitates
  436. /// method chaining.
  437. ///
  438. /// @throws
  439. /// bsoncxx::exception if the current BSON datum is a document that is waiting for a key to be
  440. /// appended to start a new key/value pair.
  441. ///
  442. core& append(std::string str);
  443. ///
  444. /// Appends a string view as a BSON UTF-8 string.
  445. ///
  446. /// @return
  447. /// A reference to the object on which this member function is being called. This facilitates
  448. /// method chaining.
  449. ///
  450. /// @throws
  451. /// bsoncxx::exception if the current BSON datum is a document that is waiting for a key to be
  452. /// appended to start a new key/value pair.
  453. ///
  454. core& append(stdx::string_view str);
  455. ///
  456. /// Appends a char* or const char*.
  457. ///
  458. /// We disable all other pointer types to prevent the surprising implicit conversion to bool.
  459. ///
  460. /// @return
  461. /// A reference to the object on which this member function is being called. This facilitates
  462. /// method chaining.
  463. ///
  464. /// @throws
  465. /// bsoncxx::exception if the current BSON datum is a document that is waiting for a key to be
  466. /// appended to start a new key/value pair.
  467. ///
  468. template <typename T>
  469. BSONCXX_INLINE core& append(T* v) {
  470. static_assert(std::is_same<typename std::remove_const<T>::type, char>::value,
  471. "append is disabled for non-char pointer types");
  472. append(types::b_utf8{v});
  473. return *this;
  474. }
  475. ///
  476. /// Appends a native boolean as a BSON boolean.
  477. ///
  478. /// @return
  479. /// A reference to the object on which this member function is being called. This facilitates
  480. /// method chaining.
  481. ///
  482. /// @throws
  483. /// bsoncxx::exception if the current BSON datum is a document that is waiting for a key to be
  484. /// appended to start a new key/value pair.
  485. ///
  486. core& append(bool value);
  487. ///
  488. /// Appends a native double as a BSON double.
  489. ///
  490. /// @return
  491. /// A reference to the object on which this member function is being called. This facilitates
  492. /// method chaining.
  493. ///
  494. /// @throws
  495. /// bsoncxx::exception if the current BSON datum is a document that is waiting for a key to be
  496. /// appended to start a new key/value pair.
  497. ///
  498. core& append(double value);
  499. ///
  500. /// Appends a native int32_t as a BSON 32-bit signed integer.
  501. ///
  502. /// @return
  503. /// A reference to the object on which this member function is being called. This facilitates
  504. /// method chaining.
  505. ///
  506. /// @throws
  507. /// bsoncxx::exception if the current BSON datum is a document that is waiting for a key to be
  508. /// appended to start a new key/value pair.
  509. ///
  510. core& append(std::int32_t value);
  511. ///
  512. /// Appends a native int64_t as a BSON 64-bit signed integer.
  513. ///
  514. /// @return
  515. /// A reference to the object on which this member function is being called. This facilitates
  516. /// method chaining.
  517. ///
  518. /// @throws
  519. /// bsoncxx::exception if the current BSON datum is a document that is waiting for a key to be
  520. /// appended to start a new key/value pair.
  521. ///
  522. core& append(std::int64_t value);
  523. ///
  524. /// Appends an oid as a BSON ObjectId.
  525. ///
  526. /// @return
  527. /// A reference to the object on which this member function is being called. This facilitates
  528. /// method chaining.
  529. ///
  530. /// @throws
  531. /// bsoncxx::exception if the current BSON datum is a document that is waiting for a key to be
  532. /// appended to start a new key/value pair.
  533. ///
  534. core& append(const oid& value);
  535. ///
  536. /// Appends a decimal128 object as a BSON Decimal128.
  537. ///
  538. /// @return
  539. /// A reference to the object on which this member function is being called. This facilitates
  540. /// method chaining.
  541. ///
  542. /// @throws
  543. /// bsoncxx::exception if the current BSON datum is a document that is waiting for a key to be
  544. /// appended to start a new key/value pair.
  545. ///
  546. core& append(decimal128 value);
  547. ///
  548. /// Appends the given document view.
  549. ///
  550. /// @return
  551. /// A reference to the object on which this member function is being called. This facilitates
  552. /// method chaining.
  553. ///
  554. /// @throws
  555. /// bsoncxx::exception if the current BSON datum is a document that is waiting for a key to be
  556. /// appended to start a new key/value pair.
  557. ///
  558. core& append(document::view view);
  559. ///
  560. /// Appends the given array view.
  561. ///
  562. /// @return
  563. /// A reference to the object on which this member function is being called. This facilitates
  564. /// method chaining.
  565. ///
  566. /// @throws
  567. /// bsoncxx::exception if the current BSON datum is a document that is waiting for a key to be
  568. /// appended to start a new key/value pair.
  569. ///
  570. core& append(array::view view);
  571. ///
  572. /// Gets a view over the document.
  573. ///
  574. /// @return A document::view of the internal BSON.
  575. ///
  576. /// @pre
  577. /// The top-level BSON datum should be a document that is not waiting for a key to be
  578. /// appended to start a new key/value pair, and does contain any open sub-documents or open
  579. /// sub-arrays.
  580. ///
  581. /// @throws bsoncxx::exception if the precondition is violated.
  582. ///
  583. document::view view_document() const;
  584. ///
  585. /// Gets a view over the array.
  586. ///
  587. /// @return An array::view of the internal BSON.
  588. ///
  589. /// @pre
  590. /// The top-level BSON datum should be an array that does not contain any open sub-documents
  591. /// or open sub-arrays.
  592. ///
  593. /// @throws bsoncxx::exception if the precondition is violated.
  594. ///
  595. array::view view_array() const;
  596. ///
  597. /// Transfers ownership of the underlying document to the caller.
  598. ///
  599. /// @return A document::value with ownership of the document.
  600. ///
  601. /// @pre
  602. /// The top-level BSON datum should be a document that is not waiting for a key to be
  603. /// appended to start a new key/value pair, and does not contain any open sub-documents or
  604. /// open sub-arrays.
  605. ///
  606. /// @throws bsoncxx::exception if the precondition is violated.
  607. ///
  608. /// @warning
  609. /// After calling extract_document() it is illegal to call any methods on this class, unless
  610. /// it is subsequenly moved into.
  611. ///
  612. document::value extract_document();
  613. ///
  614. /// Transfers ownership of the underlying document to the caller.
  615. ///
  616. /// @return A document::value with ownership of the document.
  617. ///
  618. /// @pre
  619. /// The top-level BSON datum should be an array that does not contain any open sub-documents
  620. /// or open sub-arrays.
  621. ///
  622. /// @throws bsoncxx::exception if the precondition is violated.
  623. ///
  624. /// @warning
  625. /// After calling extract_array() it is illegal to call any methods on this class, unless it
  626. /// is subsequenly moved into.
  627. ///
  628. array::value extract_array();
  629. ///
  630. /// Deletes the contents of the underlying BSON datum. After calling clear(), the state of this
  631. /// class will be the same as it was immediately after construction.
  632. ///
  633. void clear();
  634. private:
  635. std::unique_ptr<impl> _impl;
  636. };
  637. } // namespace builder
  638. BSONCXX_INLINE_NAMESPACE_END
  639. } // namespace bsoncxx
  640. #include <bsoncxx/config/postlude.hpp>