Iterator.h 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495
  1. /*
  2. * Copyright 2017-present Facebook, Inc.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #pragma once
  17. #include <functional>
  18. #include <iterator>
  19. #include <memory>
  20. #include <tuple>
  21. #include <type_traits>
  22. #include <utility>
  23. #include <folly/Utility.h>
  24. #include <folly/lang/RValueReferenceWrapper.h>
  25. namespace folly {
  26. /**
  27. * Argument tuple for variadic emplace/constructor calls. Stores arguments by
  28. * (decayed) value. Restores original argument types with reference qualifiers
  29. * and adornments at unpack time to emulate perfect forwarding.
  30. *
  31. * Uses inheritance instead of a type alias to std::tuple so that emplace
  32. * iterators with implicit unpacking disabled can distinguish between
  33. * emplace_args and std::tuple parameters.
  34. *
  35. * @seealso folly::make_emplace_args
  36. * @seealso folly::get_emplace_arg
  37. */
  38. template <typename... Args>
  39. struct emplace_args : public std::tuple<std::decay_t<Args>...> {
  40. using storage_type = std::tuple<std::decay_t<Args>...>;
  41. using storage_type::storage_type;
  42. };
  43. /**
  44. * Pack arguments in a tuple for assignment to a folly::emplace_iterator,
  45. * folly::front_emplace_iterator, or folly::back_emplace_iterator. The
  46. * iterator's operator= will unpack the tuple and pass the unpacked arguments
  47. * to the container's emplace function, which in turn forwards the arguments to
  48. * the (multi-argument) constructor of the target class.
  49. *
  50. * Argument tuples generated with folly::make_emplace_args will be unpacked
  51. * before being passed to the container's emplace function, even for iterators
  52. * where implicit_unpack is set to false (so they will not implicitly unpack
  53. * std::pair or std::tuple arguments to operator=).
  54. *
  55. * Arguments are copied (lvalues) or moved (rvalues). To avoid copies and moves,
  56. * wrap references using std::ref(), std::cref(), and folly::rref(). Beware of
  57. * dangling references, especially references to temporary objects created with
  58. * folly::rref().
  59. *
  60. * Note that an argument pack created with folly::make_emplace_args is different
  61. * from an argument pack created with std::make_pair or std::make_tuple.
  62. * Specifically, passing a std::pair&& or std::tuple&& to an emplace iterator's
  63. * operator= will pass rvalue references to all fields of that tuple to the
  64. * container's emplace function, while passing an emplace_args&& to operator=
  65. * will cast those field references to the exact argument types as passed to
  66. * folly::make_emplace_args previously. If all arguments have been wrapped by
  67. * std::reference_wrappers or folly::rvalue_reference_wrappers, the result will
  68. * be the same as if the container's emplace function had been called directly
  69. * (perfect forwarding), with no temporary copies of the arguments.
  70. *
  71. * @seealso folly::rref
  72. *
  73. * @example
  74. * class Widget { Widget(int, int); };
  75. * std::vector<Widget> makeWidgets(const std::vector<int>& in) {
  76. * std::vector<Widget> out;
  77. * std::transform(
  78. * in.begin(),
  79. * in.end(),
  80. * folly::back_emplacer(out),
  81. * [](int i) { return folly::make_emplace_args(i, i); });
  82. * return out;
  83. * }
  84. */
  85. template <typename... Args>
  86. emplace_args<Args...> make_emplace_args(Args&&... args) noexcept(
  87. noexcept(emplace_args<Args...>(std::forward<Args>(args)...))) {
  88. return emplace_args<Args...>(std::forward<Args>(args)...);
  89. }
  90. namespace detail {
  91. template <typename Arg>
  92. decltype(auto) unwrap_emplace_arg(Arg&& arg) noexcept {
  93. return std::forward<Arg>(arg);
  94. }
  95. template <typename Arg>
  96. decltype(auto) unwrap_emplace_arg(std::reference_wrapper<Arg> arg) noexcept {
  97. return arg.get();
  98. }
  99. template <typename Arg>
  100. decltype(auto) unwrap_emplace_arg(
  101. folly::rvalue_reference_wrapper<Arg> arg) noexcept {
  102. return std::move(arg).get();
  103. }
  104. } // namespace detail
  105. /**
  106. * Getter function for unpacking a single emplace argument.
  107. *
  108. * Calling get_emplace_arg on an emplace_args rvalue reference results in
  109. * perfect forwarding of the original input types. A special case are
  110. * std::reference_wrapper and folly::rvalue_reference_wrapper objects within
  111. * folly::emplace_args. These are also unwrapped so that the bare reference is
  112. * returned.
  113. *
  114. * std::get is not a customization point in the standard library, so the
  115. * cleanest solution was to define our own getter function.
  116. */
  117. template <size_t I, typename... Args>
  118. decltype(auto) get_emplace_arg(emplace_args<Args...>&& args) noexcept {
  119. using Out = std::tuple<Args...>;
  120. return detail::unwrap_emplace_arg(
  121. std::forward<std::tuple_element_t<I, Out>>(std::get<I>(args)));
  122. }
  123. template <size_t I, typename... Args>
  124. decltype(auto) get_emplace_arg(emplace_args<Args...>& args) noexcept {
  125. return detail::unwrap_emplace_arg(std::get<I>(args));
  126. }
  127. template <size_t I, typename... Args>
  128. decltype(auto) get_emplace_arg(const emplace_args<Args...>& args) noexcept {
  129. return detail::unwrap_emplace_arg(std::get<I>(args));
  130. }
  131. template <size_t I, typename Args>
  132. decltype(auto) get_emplace_arg(Args&& args) noexcept {
  133. return std::get<I>(std::move(args));
  134. }
  135. template <size_t I, typename Args>
  136. decltype(auto) get_emplace_arg(Args& args) noexcept {
  137. return std::get<I>(args);
  138. }
  139. template <size_t I, typename Args>
  140. decltype(auto) get_emplace_arg(const Args& args) noexcept {
  141. return std::get<I>(args);
  142. }
  143. namespace detail {
  144. /**
  145. * Emplace implementation class for folly::emplace_iterator.
  146. */
  147. template <typename Container>
  148. struct Emplace {
  149. Emplace(Container& c, typename Container::iterator i)
  150. : container(std::addressof(c)), iter(std::move(i)) {}
  151. template <typename... Args>
  152. void emplace(Args&&... args) {
  153. iter = container->emplace(iter, std::forward<Args>(args)...);
  154. ++iter;
  155. }
  156. Container* container;
  157. typename Container::iterator iter;
  158. };
  159. /**
  160. * Emplace implementation class for folly::hint_emplace_iterator.
  161. */
  162. template <typename Container>
  163. struct EmplaceHint {
  164. EmplaceHint(Container& c, typename Container::iterator i)
  165. : container(std::addressof(c)), iter(std::move(i)) {}
  166. template <typename... Args>
  167. void emplace(Args&&... args) {
  168. iter = container->emplace_hint(iter, std::forward<Args>(args)...);
  169. ++iter;
  170. }
  171. Container* container;
  172. typename Container::iterator iter;
  173. };
  174. /**
  175. * Emplace implementation class for folly::front_emplace_iterator.
  176. */
  177. template <typename Container>
  178. struct EmplaceFront {
  179. explicit EmplaceFront(Container& c) : container(std::addressof(c)) {}
  180. template <typename... Args>
  181. void emplace(Args&&... args) {
  182. container->emplace_front(std::forward<Args>(args)...);
  183. }
  184. Container* container;
  185. };
  186. /**
  187. * Emplace implementation class for folly::back_emplace_iterator.
  188. */
  189. template <typename Container>
  190. struct EmplaceBack {
  191. explicit EmplaceBack(Container& c) : container(std::addressof(c)) {}
  192. template <typename... Args>
  193. void emplace(Args&&... args) {
  194. container->emplace_back(std::forward<Args>(args)...);
  195. }
  196. Container* container;
  197. };
  198. /**
  199. * Generic base class and implementation of all emplace iterator classes.
  200. *
  201. * Uses the curiously recurring template pattern (CRTP) to cast `this*` to
  202. * `Derived*`; i.e., to implement covariant return types in a generic manner.
  203. */
  204. template <typename Derived, typename EmplaceImpl, bool implicit_unpack>
  205. class emplace_iterator_base;
  206. /**
  207. * Partial specialization of emplace_iterator_base with implicit unpacking
  208. * disabled.
  209. */
  210. template <typename Derived, typename EmplaceImpl>
  211. class emplace_iterator_base<Derived, EmplaceImpl, false>
  212. : protected EmplaceImpl /* protected implementation inheritance */ {
  213. public:
  214. // Iterator traits.
  215. using iterator_category = std::output_iterator_tag;
  216. using value_type = void;
  217. using difference_type = void;
  218. using pointer = void;
  219. using reference = void;
  220. using container_type =
  221. std::remove_reference_t<decltype(*EmplaceImpl::container)>;
  222. using EmplaceImpl::EmplaceImpl;
  223. /**
  224. * Canonical output operator. Forwards single argument straight to container's
  225. * emplace function.
  226. */
  227. template <typename T>
  228. Derived& operator=(T&& arg) {
  229. this->emplace(std::forward<T>(arg));
  230. return static_cast<Derived&>(*this);
  231. }
  232. /**
  233. * Special output operator for packed arguments. Unpacks args and performs
  234. * variadic call to container's emplace function.
  235. */
  236. template <typename... Args>
  237. Derived& operator=(emplace_args<Args...>& args) {
  238. return unpackAndEmplace(args, index_sequence_for<Args...>{});
  239. }
  240. template <typename... Args>
  241. Derived& operator=(const emplace_args<Args...>& args) {
  242. return unpackAndEmplace(args, index_sequence_for<Args...>{});
  243. }
  244. template <typename... Args>
  245. Derived& operator=(emplace_args<Args...>&& args) {
  246. return unpackAndEmplace(std::move(args), index_sequence_for<Args...>{});
  247. }
  248. // No-ops.
  249. Derived& operator*() {
  250. return static_cast<Derived&>(*this);
  251. }
  252. Derived& operator++() {
  253. return static_cast<Derived&>(*this);
  254. }
  255. Derived& operator++(int) {
  256. return static_cast<Derived&>(*this);
  257. }
  258. // We need all of these explicit defaults because the custom operator=
  259. // overloads disable implicit generation of these functions.
  260. emplace_iterator_base(const emplace_iterator_base&) = default;
  261. emplace_iterator_base(emplace_iterator_base&&) noexcept = default;
  262. emplace_iterator_base& operator=(emplace_iterator_base&) = default;
  263. emplace_iterator_base& operator=(const emplace_iterator_base&) = default;
  264. emplace_iterator_base& operator=(emplace_iterator_base&&) noexcept = default;
  265. protected:
  266. template <typename Args, std::size_t... I>
  267. Derived& unpackAndEmplace(Args& args, index_sequence<I...>) {
  268. this->emplace(get_emplace_arg<I>(args)...);
  269. return static_cast<Derived&>(*this);
  270. }
  271. template <typename Args, std::size_t... I>
  272. Derived& unpackAndEmplace(const Args& args, index_sequence<I...>) {
  273. this->emplace(get_emplace_arg<I>(args)...);
  274. return static_cast<Derived&>(*this);
  275. }
  276. template <typename Args, std::size_t... I>
  277. Derived& unpackAndEmplace(Args&& args, index_sequence<I...>) {
  278. this->emplace(get_emplace_arg<I>(std::move(args))...);
  279. return static_cast<Derived&>(*this);
  280. }
  281. };
  282. /**
  283. * Partial specialization of emplace_iterator_base with implicit unpacking
  284. * enabled.
  285. *
  286. * Uses inheritance rather than SFINAE. operator= requires a single argument,
  287. * which makes it very tricky to use std::enable_if or similar.
  288. */
  289. template <typename Derived, typename EmplaceImpl>
  290. class emplace_iterator_base<Derived, EmplaceImpl, true>
  291. : public emplace_iterator_base<Derived, EmplaceImpl, false> {
  292. private:
  293. using Base = emplace_iterator_base<Derived, EmplaceImpl, false>;
  294. public:
  295. using Base::Base;
  296. using Base::operator=;
  297. /**
  298. * Special output operator for arguments packed into a std::pair. Unpacks
  299. * the pair and performs variadic call to container's emplace function.
  300. */
  301. template <typename... Args>
  302. Derived& operator=(std::pair<Args...>& args) {
  303. return this->unpackAndEmplace(args, index_sequence_for<Args...>{});
  304. }
  305. template <typename... Args>
  306. Derived& operator=(const std::pair<Args...>& args) {
  307. return this->unpackAndEmplace(args, index_sequence_for<Args...>{});
  308. }
  309. template <typename... Args>
  310. Derived& operator=(std::pair<Args...>&& args) {
  311. return this->unpackAndEmplace(
  312. std::move(args), index_sequence_for<Args...>{});
  313. }
  314. /**
  315. * Special output operator for arguments packed into a std::tuple. Unpacks
  316. * the tuple and performs variadic call to container's emplace function.
  317. */
  318. template <typename... Args>
  319. Derived& operator=(std::tuple<Args...>& args) {
  320. return this->unpackAndEmplace(args, index_sequence_for<Args...>{});
  321. }
  322. template <typename... Args>
  323. Derived& operator=(const std::tuple<Args...>& args) {
  324. return this->unpackAndEmplace(args, index_sequence_for<Args...>{});
  325. }
  326. template <typename... Args>
  327. Derived& operator=(std::tuple<Args...>&& args) {
  328. return this->unpackAndEmplace(
  329. std::move(args), index_sequence_for<Args...>{});
  330. }
  331. // We need all of these explicit defaults because the custom operator=
  332. // overloads disable implicit generation of these functions.
  333. emplace_iterator_base(const emplace_iterator_base&) = default;
  334. emplace_iterator_base(emplace_iterator_base&&) noexcept = default;
  335. emplace_iterator_base& operator=(emplace_iterator_base&) = default;
  336. emplace_iterator_base& operator=(const emplace_iterator_base&) = default;
  337. emplace_iterator_base& operator=(emplace_iterator_base&&) noexcept = default;
  338. };
  339. /**
  340. * Concrete instantiation of emplace_iterator_base. All emplace iterator
  341. * classes; folly::emplace_iterator, folly::hint_emplace_iterator,
  342. * folly::front_emplace_iterator, and folly::back_emplace_iterator; are just
  343. * type aliases of this class.
  344. *
  345. * It is not possible to alias emplace_iterator_base directly, because type
  346. * aliases cannot be used for CRTP.
  347. */
  348. template <
  349. template <typename> class EmplaceImplT,
  350. typename Container,
  351. bool implicit_unpack>
  352. class emplace_iterator_impl
  353. : public emplace_iterator_base<
  354. emplace_iterator_impl<EmplaceImplT, Container, implicit_unpack>,
  355. EmplaceImplT<Container>,
  356. implicit_unpack> {
  357. private:
  358. using Base = emplace_iterator_base<
  359. emplace_iterator_impl,
  360. EmplaceImplT<Container>,
  361. implicit_unpack>;
  362. public:
  363. using Base::Base;
  364. using Base::operator=;
  365. // We need all of these explicit defaults because the custom operator=
  366. // overloads disable implicit generation of these functions.
  367. emplace_iterator_impl(const emplace_iterator_impl&) = default;
  368. emplace_iterator_impl(emplace_iterator_impl&&) noexcept = default;
  369. emplace_iterator_impl& operator=(emplace_iterator_impl&) = default;
  370. emplace_iterator_impl& operator=(const emplace_iterator_impl&) = default;
  371. emplace_iterator_impl& operator=(emplace_iterator_impl&&) noexcept = default;
  372. };
  373. } // namespace detail
  374. /**
  375. * Behaves just like std::insert_iterator except that it calls emplace()
  376. * instead of insert(). Uses perfect forwarding.
  377. */
  378. template <typename Container, bool implicit_unpack = true>
  379. using emplace_iterator =
  380. detail::emplace_iterator_impl<detail::Emplace, Container, implicit_unpack>;
  381. /**
  382. * Behaves just like std::insert_iterator except that it calls emplace_hint()
  383. * instead of insert(). Uses perfect forwarding.
  384. */
  385. template <typename Container, bool implicit_unpack = true>
  386. using hint_emplace_iterator = detail::
  387. emplace_iterator_impl<detail::EmplaceHint, Container, implicit_unpack>;
  388. /**
  389. * Behaves just like std::front_insert_iterator except that it calls
  390. * emplace_front() instead of insert(). Uses perfect forwarding.
  391. */
  392. template <typename Container, bool implicit_unpack = true>
  393. using front_emplace_iterator = detail::
  394. emplace_iterator_impl<detail::EmplaceFront, Container, implicit_unpack>;
  395. /**
  396. * Behaves just like std::back_insert_iterator except that it calls
  397. * emplace_back() instead of insert(). Uses perfect forwarding.
  398. */
  399. template <typename Container, bool implicit_unpack = true>
  400. using back_emplace_iterator = detail::
  401. emplace_iterator_impl<detail::EmplaceBack, Container, implicit_unpack>;
  402. /**
  403. * Convenience function to construct a folly::emplace_iterator, analogous to
  404. * std::inserter().
  405. *
  406. * Setting implicit_unpack to false will disable implicit unpacking of
  407. * single std::pair and std::tuple arguments to the iterator's operator=. That
  408. * may be desirable in case of constructors that expect a std::pair or
  409. * std::tuple argument.
  410. */
  411. template <bool implicit_unpack = true, typename Container>
  412. emplace_iterator<Container, implicit_unpack> emplacer(
  413. Container& c,
  414. typename Container::iterator i) {
  415. return emplace_iterator<Container, implicit_unpack>(c, std::move(i));
  416. }
  417. /**
  418. * Convenience function to construct a folly::hint_emplace_iterator, analogous
  419. * to std::inserter().
  420. *
  421. * Setting implicit_unpack to false will disable implicit unpacking of
  422. * single std::pair and std::tuple arguments to the iterator's operator=. That
  423. * may be desirable in case of constructors that expect a std::pair or
  424. * std::tuple argument.
  425. */
  426. template <bool implicit_unpack = true, typename Container>
  427. hint_emplace_iterator<Container, implicit_unpack> hint_emplacer(
  428. Container& c,
  429. typename Container::iterator i) {
  430. return hint_emplace_iterator<Container, implicit_unpack>(c, std::move(i));
  431. }
  432. /**
  433. * Convenience function to construct a folly::front_emplace_iterator, analogous
  434. * to std::front_inserter().
  435. *
  436. * Setting implicit_unpack to false will disable implicit unpacking of
  437. * single std::pair and std::tuple arguments to the iterator's operator=. That
  438. * may be desirable in case of constructors that expect a std::pair or
  439. * std::tuple argument.
  440. */
  441. template <bool implicit_unpack = true, typename Container>
  442. front_emplace_iterator<Container, implicit_unpack> front_emplacer(
  443. Container& c) {
  444. return front_emplace_iterator<Container, implicit_unpack>(c);
  445. }
  446. /**
  447. * Convenience function to construct a folly::back_emplace_iterator, analogous
  448. * to std::back_inserter().
  449. *
  450. * Setting implicit_unpack to false will disable implicit unpacking of
  451. * single std::pair and std::tuple arguments to the iterator's operator=. That
  452. * may be desirable in case of constructors that expect a std::pair or
  453. * std::tuple argument.
  454. */
  455. template <bool implicit_unpack = true, typename Container>
  456. back_emplace_iterator<Container, implicit_unpack> back_emplacer(Container& c) {
  457. return back_emplace_iterator<Container, implicit_unpack>(c);
  458. }
  459. } // namespace folly