Base.h 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854
  1. /*
  2. * Copyright 2014-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. #define FOLLY_GEN_BASE_H_
  18. #include <algorithm>
  19. #include <functional>
  20. #include <memory>
  21. #include <random>
  22. #include <type_traits>
  23. #include <unordered_map>
  24. #include <unordered_set>
  25. #include <utility>
  26. #include <vector>
  27. #include <folly/Conv.h>
  28. #include <folly/Optional.h>
  29. #include <folly/Range.h>
  30. #include <folly/Utility.h>
  31. #include <folly/gen/Core.h>
  32. /**
  33. * Generator-based Sequence Comprehensions in C++, akin to C#'s LINQ
  34. * @author Tom Jackson <tjackson@fb.com>
  35. *
  36. * This library makes it possible to write declarative comprehensions for
  37. * processing sequences of values efficiently in C++. The operators should be
  38. * familiar to those with experience in functional programming, and the
  39. * performance will be virtually identical to the equivalent, boilerplate C++
  40. * implementations.
  41. *
  42. * Generator objects may be created from either an stl-like container (anything
  43. * supporting begin() and end()), from sequences of values, or from another
  44. * generator (see below). To create a generator that pulls values from a vector,
  45. * for example, one could write:
  46. *
  47. * vector<string> names { "Jack", "Jill", "Sara", "Tom" };
  48. * auto gen = from(names);
  49. *
  50. * Generators are composed by building new generators out of old ones through
  51. * the use of operators. These are reminicent of shell pipelines, and afford
  52. * similar composition. Lambda functions are used liberally to describe how to
  53. * handle individual values:
  54. *
  55. * auto lengths = gen
  56. * | mapped([](const fbstring& name) { return name.size(); });
  57. *
  58. * Generators are lazy; they don't actually perform any work until they need to.
  59. * As an example, the 'lengths' generator (above) won't actually invoke the
  60. * provided lambda until values are needed:
  61. *
  62. * auto lengthVector = lengths | as<std::vector>();
  63. * auto totalLength = lengths | sum;
  64. *
  65. * 'auto' is useful in here because the actual types of the generators objects
  66. * are usually complicated and implementation-sensitive.
  67. *
  68. * If a simpler type is desired (for returning, as an example), VirtualGen<T>
  69. * may be used to wrap the generator in a polymorphic wrapper:
  70. *
  71. * VirtualGen<float> powersOfE() {
  72. * return seq(1) | mapped(&expf);
  73. * }
  74. *
  75. * To learn more about this library, including the use of infinite generators,
  76. * see the examples in the comments, or the docs (coming soon).
  77. */
  78. namespace folly {
  79. namespace gen {
  80. class Less {
  81. public:
  82. template <class First, class Second>
  83. auto operator()(const First& first, const Second& second) const
  84. -> decltype(first < second) {
  85. return first < second;
  86. }
  87. };
  88. class Greater {
  89. public:
  90. template <class First, class Second>
  91. auto operator()(const First& first, const Second& second) const
  92. -> decltype(first > second) {
  93. return first > second;
  94. }
  95. };
  96. template <int n>
  97. class Get {
  98. public:
  99. template <class Value>
  100. auto operator()(Value&& value) const
  101. -> decltype(std::get<n>(std::forward<Value>(value))) {
  102. return std::get<n>(std::forward<Value>(value));
  103. }
  104. };
  105. template <class Class, class Result>
  106. class MemberFunction {
  107. public:
  108. typedef Result (Class::*MemberPtr)();
  109. private:
  110. MemberPtr member_;
  111. public:
  112. explicit MemberFunction(MemberPtr member) : member_(member) {}
  113. Result operator()(Class&& x) const {
  114. return (x.*member_)();
  115. }
  116. Result operator()(Class& x) const {
  117. return (x.*member_)();
  118. }
  119. Result operator()(Class* x) const {
  120. return (x->*member_)();
  121. }
  122. };
  123. template <class Class, class Result>
  124. class ConstMemberFunction {
  125. public:
  126. typedef Result (Class::*MemberPtr)() const;
  127. private:
  128. MemberPtr member_;
  129. public:
  130. explicit ConstMemberFunction(MemberPtr member) : member_(member) {}
  131. Result operator()(const Class& x) const {
  132. return (x.*member_)();
  133. }
  134. Result operator()(const Class* x) const {
  135. return (x->*member_)();
  136. }
  137. };
  138. template <class Class, class FieldType>
  139. class Field {
  140. public:
  141. typedef FieldType(Class::*FieldPtr);
  142. private:
  143. FieldPtr field_;
  144. public:
  145. explicit Field(FieldPtr field) : field_(field) {}
  146. const FieldType& operator()(const Class& x) const {
  147. return x.*field_;
  148. }
  149. const FieldType& operator()(const Class* x) const {
  150. return x->*field_;
  151. }
  152. FieldType& operator()(Class& x) const {
  153. return x.*field_;
  154. }
  155. FieldType& operator()(Class* x) const {
  156. return x->*field_;
  157. }
  158. FieldType&& operator()(Class&& x) const {
  159. return std::move(x.*field_);
  160. }
  161. };
  162. class Move {
  163. public:
  164. template <class Value>
  165. auto operator()(Value&& value) const
  166. -> decltype(std::move(std::forward<Value>(value))) {
  167. return std::move(std::forward<Value>(value));
  168. }
  169. };
  170. /**
  171. * Class and helper function for negating a boolean Predicate
  172. */
  173. template <class Predicate>
  174. class Negate {
  175. Predicate pred_;
  176. public:
  177. Negate() = default;
  178. explicit Negate(Predicate pred) : pred_(std::move(pred)) {}
  179. template <class Arg>
  180. bool operator()(Arg&& arg) const {
  181. return !pred_(std::forward<Arg>(arg));
  182. }
  183. };
  184. template <class Predicate>
  185. Negate<Predicate> negate(Predicate pred) {
  186. return Negate<Predicate>(std::move(pred));
  187. }
  188. template <class Dest>
  189. class Cast {
  190. public:
  191. template <class Value>
  192. Dest operator()(Value&& value) const {
  193. return Dest(std::forward<Value>(value));
  194. }
  195. };
  196. template <class Dest>
  197. class To {
  198. public:
  199. template <class Value>
  200. Dest operator()(Value&& value) const {
  201. return ::folly::to<Dest>(std::forward<Value>(value));
  202. }
  203. };
  204. template <class Dest>
  205. class TryTo {
  206. public:
  207. template <class Value>
  208. Expected<Dest, ConversionCode> operator()(Value&& value) const {
  209. return ::folly::tryTo<Dest>(std::forward<Value>(value));
  210. }
  211. };
  212. // Specialization to allow String->StringPiece conversion
  213. template <>
  214. class To<StringPiece> {
  215. public:
  216. StringPiece operator()(StringPiece src) const {
  217. return src;
  218. }
  219. };
  220. template <class Key, class Value>
  221. class Group;
  222. namespace detail {
  223. template <class Self>
  224. struct FBounded;
  225. /*
  226. * Type Traits
  227. */
  228. template <class Container>
  229. struct ValueTypeOfRange {
  230. public:
  231. using RefType = decltype(*std::begin(std::declval<Container&>()));
  232. using StorageType = typename std::decay<RefType>::type;
  233. };
  234. /*
  235. * Sources
  236. */
  237. template <
  238. class Container,
  239. class Value = typename ValueTypeOfRange<Container>::RefType>
  240. class ReferencedSource;
  241. template <
  242. class Value,
  243. class Container = std::vector<typename std::decay<Value>::type>>
  244. class CopiedSource;
  245. template <class Value, class SequenceImpl>
  246. class Sequence;
  247. template <class Value>
  248. class RangeImpl;
  249. template <class Value, class Distance>
  250. class RangeWithStepImpl;
  251. template <class Value>
  252. class SeqImpl;
  253. template <class Value, class Distance>
  254. class SeqWithStepImpl;
  255. template <class Value>
  256. class InfiniteImpl;
  257. template <class Value, class Source>
  258. class Yield;
  259. template <class Value>
  260. class Empty;
  261. template <class Value>
  262. class SingleReference;
  263. template <class Value>
  264. class SingleCopy;
  265. /*
  266. * Operators
  267. */
  268. template <class Predicate>
  269. class Map;
  270. template <class Predicate>
  271. class Filter;
  272. template <class Predicate>
  273. class Until;
  274. class Take;
  275. class Stride;
  276. template <class Rand>
  277. class Sample;
  278. class Skip;
  279. template <class Visitor>
  280. class Visit;
  281. template <class Selector, class Comparer = Less>
  282. class Order;
  283. template <class Selector>
  284. class GroupBy;
  285. template <class Selector>
  286. class GroupByAdjacent;
  287. template <class Selector>
  288. class Distinct;
  289. template <class Operators>
  290. class Composer;
  291. template <class Expected>
  292. class TypeAssertion;
  293. class Concat;
  294. class RangeConcat;
  295. template <bool forever>
  296. class Cycle;
  297. class Batch;
  298. class Window;
  299. class Dereference;
  300. class Indirect;
  301. /*
  302. * Sinks
  303. */
  304. template <class Seed, class Fold>
  305. class FoldLeft;
  306. class First;
  307. template <bool result>
  308. class IsEmpty;
  309. template <class Reducer>
  310. class Reduce;
  311. class Sum;
  312. template <class Selector, class Comparer>
  313. class Min;
  314. template <class Container>
  315. class Collect;
  316. template <
  317. template <class, class> class Collection = std::vector,
  318. template <class> class Allocator = std::allocator>
  319. class CollectTemplate;
  320. template <class Collection>
  321. class Append;
  322. template <class Value>
  323. struct GeneratorBuilder;
  324. template <class Needle>
  325. class Contains;
  326. template <class Exception, class ErrorHandler>
  327. class GuardImpl;
  328. template <class T>
  329. class UnwrapOr;
  330. class Unwrap;
  331. } // namespace detail
  332. /**
  333. * Polymorphic wrapper
  334. **/
  335. template <class Value>
  336. class VirtualGen;
  337. /*
  338. * Source Factories
  339. */
  340. template <
  341. class Container,
  342. class From = detail::ReferencedSource<const Container>>
  343. From fromConst(const Container& source) {
  344. return From(&source);
  345. }
  346. template <class Container, class From = detail::ReferencedSource<Container>>
  347. From from(Container& source) {
  348. return From(&source);
  349. }
  350. template <
  351. class Container,
  352. class Value = typename detail::ValueTypeOfRange<Container>::StorageType,
  353. class CopyOf = detail::CopiedSource<Value>>
  354. CopyOf fromCopy(Container&& source) {
  355. return CopyOf(std::forward<Container>(source));
  356. }
  357. template <class Value, class From = detail::CopiedSource<Value>>
  358. From from(std::initializer_list<Value> source) {
  359. return From(source);
  360. }
  361. template <
  362. class Container,
  363. class From =
  364. detail::CopiedSource<typename Container::value_type, Container>>
  365. From from(Container&& source) {
  366. return From(std::move(source));
  367. }
  368. template <
  369. class Value,
  370. class Impl = detail::RangeImpl<Value>,
  371. class Gen = detail::Sequence<Value, Impl>>
  372. Gen range(Value begin, Value end) {
  373. return Gen{std::move(begin), Impl{std::move(end)}};
  374. }
  375. template <
  376. class Value,
  377. class Distance,
  378. class Impl = detail::RangeWithStepImpl<Value, Distance>,
  379. class Gen = detail::Sequence<Value, Impl>>
  380. Gen range(Value begin, Value end, Distance step) {
  381. return Gen{std::move(begin), Impl{std::move(end), std::move(step)}};
  382. }
  383. template <
  384. class Value,
  385. class Impl = detail::SeqImpl<Value>,
  386. class Gen = detail::Sequence<Value, Impl>>
  387. Gen seq(Value first, Value last) {
  388. return Gen{std::move(first), Impl{std::move(last)}};
  389. }
  390. template <
  391. class Value,
  392. class Distance,
  393. class Impl = detail::SeqWithStepImpl<Value, Distance>,
  394. class Gen = detail::Sequence<Value, Impl>>
  395. Gen seq(Value first, Value last, Distance step) {
  396. return Gen{std::move(first), Impl{std::move(last), std::move(step)}};
  397. }
  398. template <
  399. class Value,
  400. class Impl = detail::InfiniteImpl<Value>,
  401. class Gen = detail::Sequence<Value, Impl>>
  402. Gen seq(Value first) {
  403. return Gen{std::move(first), Impl{}};
  404. }
  405. template <class Value, class Source, class Yield = detail::Yield<Value, Source>>
  406. Yield generator(Source&& source) {
  407. return Yield(std::forward<Source>(source));
  408. }
  409. /*
  410. * Create inline generator, used like:
  411. *
  412. * auto gen = GENERATOR(int) { yield(1); yield(2); };
  413. */
  414. #define GENERATOR(TYPE) \
  415. ::folly::gen::detail::GeneratorBuilder<TYPE>() + [=](auto&& yield)
  416. /*
  417. * empty() - for producing empty sequences.
  418. */
  419. template <class Value>
  420. detail::Empty<Value> empty() {
  421. return {};
  422. }
  423. template <
  424. class Value,
  425. class Just = typename std::conditional<
  426. std::is_reference<Value>::value,
  427. detail::SingleReference<typename std::remove_reference<Value>::type>,
  428. detail::SingleCopy<Value>>::type>
  429. Just just(Value&& value) {
  430. return Just(std::forward<Value>(value));
  431. }
  432. /*
  433. * Operator Factories
  434. */
  435. template <class Predicate, class Map = detail::Map<Predicate>>
  436. Map mapped(Predicate pred = Predicate()) {
  437. return Map(std::move(pred));
  438. }
  439. template <class Predicate, class Map = detail::Map<Predicate>>
  440. Map map(Predicate pred = Predicate()) {
  441. return Map(std::move(pred));
  442. }
  443. /**
  444. * mapOp - Given a generator of generators, maps the application of the given
  445. * operator on to each inner gen. Especially useful in aggregating nested data
  446. * structures:
  447. *
  448. * chunked(samples, 256)
  449. * | mapOp(filter(sampleTest) | count)
  450. * | sum;
  451. */
  452. template <class Operator, class Map = detail::Map<detail::Composer<Operator>>>
  453. Map mapOp(Operator op) {
  454. return Map(detail::Composer<Operator>(std::move(op)));
  455. }
  456. /*
  457. * member(...) - For extracting a member from each value.
  458. *
  459. * vector<string> strings = ...;
  460. * auto sizes = from(strings) | member(&string::size);
  461. *
  462. * If a member is const overridden (like 'front()'), pass template parameter
  463. * 'Const' to select the const version, or 'Mutable' to select the non-const
  464. * version:
  465. *
  466. * auto heads = from(strings) | member<Const>(&string::front);
  467. */
  468. enum MemberType {
  469. Const,
  470. Mutable,
  471. };
  472. /**
  473. * These exist because MSVC has problems with expression SFINAE in templates
  474. * assignment and comparisons don't work properly without being pulled out
  475. * of the template declaration
  476. */
  477. template <MemberType Constness>
  478. struct ExprIsConst {
  479. enum {
  480. value = Constness == Const,
  481. };
  482. };
  483. template <MemberType Constness>
  484. struct ExprIsMutable {
  485. enum {
  486. value = Constness == Mutable,
  487. };
  488. };
  489. template <
  490. MemberType Constness = Const,
  491. class Class,
  492. class Return,
  493. class Mem = ConstMemberFunction<Class, Return>,
  494. class Map = detail::Map<Mem>>
  495. typename std::enable_if<ExprIsConst<Constness>::value, Map>::type member(
  496. Return (Class::*member)() const) {
  497. return Map(Mem(member));
  498. }
  499. template <
  500. MemberType Constness = Mutable,
  501. class Class,
  502. class Return,
  503. class Mem = MemberFunction<Class, Return>,
  504. class Map = detail::Map<Mem>>
  505. typename std::enable_if<ExprIsMutable<Constness>::value, Map>::type member(
  506. Return (Class::*member)()) {
  507. return Map(Mem(member));
  508. }
  509. /*
  510. * field(...) - For extracting a field from each value.
  511. *
  512. * vector<Item> items = ...;
  513. * auto names = from(items) | field(&Item::name);
  514. *
  515. * Note that if the values of the generator are rvalues, any non-reference
  516. * fields will be rvalues as well. As an example, the code below does not copy
  517. * any strings, only moves them:
  518. *
  519. * auto namesVector = from(items)
  520. * | move
  521. * | field(&Item::name)
  522. * | as<vector>();
  523. */
  524. template <
  525. class Class,
  526. class FieldType,
  527. class Field = Field<Class, FieldType>,
  528. class Map = detail::Map<Field>>
  529. Map field(FieldType Class::*field) {
  530. return Map(Field(field));
  531. }
  532. template <class Predicate = Identity, class Filter = detail::Filter<Predicate>>
  533. Filter filter(Predicate pred = Predicate()) {
  534. return Filter(std::move(pred));
  535. }
  536. template <class Visitor = Ignore, class Visit = detail::Visit<Visitor>>
  537. Visit visit(Visitor visitor = Visitor()) {
  538. return Visit(std::move(visitor));
  539. }
  540. template <class Predicate = Identity, class Until = detail::Until<Predicate>>
  541. Until until(Predicate pred = Predicate()) {
  542. return Until(std::move(pred));
  543. }
  544. template <
  545. class Predicate = Identity,
  546. class TakeWhile = detail::Until<Negate<Predicate>>>
  547. TakeWhile takeWhile(Predicate pred = Predicate()) {
  548. return TakeWhile(Negate<Predicate>(std::move(pred)));
  549. }
  550. template <
  551. class Selector = Identity,
  552. class Comparer = Less,
  553. class Order = detail::Order<Selector, Comparer>>
  554. Order orderBy(Selector selector = Selector(), Comparer comparer = Comparer()) {
  555. return Order(std::move(selector), std::move(comparer));
  556. }
  557. template <
  558. class Selector = Identity,
  559. class Order = detail::Order<Selector, Greater>>
  560. Order orderByDescending(Selector selector = Selector()) {
  561. return Order(std::move(selector));
  562. }
  563. template <class Selector = Identity, class GroupBy = detail::GroupBy<Selector>>
  564. GroupBy groupBy(Selector selector = Selector()) {
  565. return GroupBy(std::move(selector));
  566. }
  567. template <
  568. class Selector = Identity,
  569. class GroupByAdjacent = detail::GroupByAdjacent<Selector>>
  570. GroupByAdjacent groupByAdjacent(Selector selector = Selector()) {
  571. return GroupByAdjacent(std::move(selector));
  572. }
  573. template <
  574. class Selector = Identity,
  575. class Distinct = detail::Distinct<Selector>>
  576. Distinct distinctBy(Selector selector = Selector()) {
  577. return Distinct(std::move(selector));
  578. }
  579. template <int n, class Get = detail::Map<Get<n>>>
  580. Get get() {
  581. return Get();
  582. }
  583. // construct Dest from each value
  584. template <class Dest, class Cast = detail::Map<Cast<Dest>>>
  585. Cast eachAs() {
  586. return Cast();
  587. }
  588. // call folly::to on each value
  589. template <class Dest, class EachTo = detail::Map<To<Dest>>>
  590. EachTo eachTo() {
  591. return EachTo();
  592. }
  593. // call folly::tryTo on each value
  594. template <class Dest, class EachTryTo = detail::Map<TryTo<Dest>>>
  595. EachTryTo eachTryTo() {
  596. return EachTryTo();
  597. }
  598. template <class Value>
  599. detail::TypeAssertion<Value> assert_type() {
  600. return {};
  601. }
  602. /*
  603. * Sink Factories
  604. */
  605. /**
  606. * any() - For determining if any value in a sequence satisfies a predicate.
  607. *
  608. * The following is an example for checking if any computer is broken:
  609. *
  610. * bool schrepIsMad = from(computers) | any(isBroken);
  611. *
  612. * (because everyone knows Schrep hates broken computers).
  613. *
  614. * Note that if no predicate is provided, 'any()' checks if any of the values
  615. * are true when cased to bool. To check if any of the scores are nonZero:
  616. *
  617. * bool somebodyScored = from(scores) | any();
  618. *
  619. * Note: Passing an empty sequence through 'any()' will always return false. In
  620. * fact, 'any()' is equivilent to the composition of 'filter()' and 'notEmpty'.
  621. *
  622. * from(source) | any(pred) == from(source) | filter(pred) | notEmpty
  623. */
  624. template <
  625. class Predicate = Identity,
  626. class Filter = detail::Filter<Predicate>,
  627. class NotEmpty = detail::IsEmpty<false>,
  628. class Composed = detail::Composed<Filter, NotEmpty>>
  629. Composed any(Predicate pred = Predicate()) {
  630. return Composed(Filter(std::move(pred)), NotEmpty());
  631. }
  632. /**
  633. * all() - For determining whether all values in a sequence satisfy a predicate.
  634. *
  635. * The following is an example for checking if all members of a team are cool:
  636. *
  637. * bool isAwesomeTeam = from(team) | all(isCool);
  638. *
  639. * Note that if no predicate is provided, 'all()'' checks if all of the values
  640. * are true when cased to bool.
  641. * The following makes sure none of 'pointers' are nullptr:
  642. *
  643. * bool allNonNull = from(pointers) | all();
  644. *
  645. * Note: Passing an empty sequence through 'all()' will always return true. In
  646. * fact, 'all()' is equivilent to the composition of 'filter()' with the
  647. * reversed predicate and 'isEmpty'.
  648. *
  649. * from(source) | all(pred) == from(source) | filter(negate(pred)) | isEmpty
  650. */
  651. template <
  652. class Predicate = Identity,
  653. class Filter = detail::Filter<Negate<Predicate>>,
  654. class IsEmpty = detail::IsEmpty<true>,
  655. class Composed = detail::Composed<Filter, IsEmpty>>
  656. Composed all(Predicate pred = Predicate()) {
  657. return Composed(Filter(std::move(negate(pred))), IsEmpty());
  658. }
  659. template <class Seed, class Fold, class FoldLeft = detail::FoldLeft<Seed, Fold>>
  660. FoldLeft foldl(Seed seed = Seed(), Fold fold = Fold()) {
  661. return FoldLeft(std::move(seed), std::move(fold));
  662. }
  663. template <class Reducer, class Reduce = detail::Reduce<Reducer>>
  664. Reduce reduce(Reducer reducer = Reducer()) {
  665. return Reduce(std::move(reducer));
  666. }
  667. template <class Selector = Identity, class Min = detail::Min<Selector, Less>>
  668. Min minBy(Selector selector = Selector()) {
  669. return Min(std::move(selector));
  670. }
  671. template <class Selector, class MaxBy = detail::Min<Selector, Greater>>
  672. MaxBy maxBy(Selector selector = Selector()) {
  673. return MaxBy(std::move(selector));
  674. }
  675. template <class Collection, class Collect = detail::Collect<Collection>>
  676. Collect as() {
  677. return Collect();
  678. }
  679. template <
  680. template <class, class> class Container = std::vector,
  681. template <class> class Allocator = std::allocator,
  682. class Collect = detail::CollectTemplate<Container, Allocator>>
  683. Collect as() {
  684. return Collect();
  685. }
  686. template <class Collection, class Append = detail::Append<Collection>>
  687. Append appendTo(Collection& collection) {
  688. return Append(&collection);
  689. }
  690. template <
  691. class Needle,
  692. class Contains = detail::Contains<typename std::decay<Needle>::type>>
  693. Contains contains(Needle&& needle) {
  694. return Contains(std::forward<Needle>(needle));
  695. }
  696. template <
  697. class Exception,
  698. class ErrorHandler,
  699. class GuardImpl =
  700. detail::GuardImpl<Exception, typename std::decay<ErrorHandler>::type>>
  701. GuardImpl guard(ErrorHandler&& handler) {
  702. return GuardImpl(std::forward<ErrorHandler>(handler));
  703. }
  704. template <
  705. class Fallback,
  706. class UnwrapOr = detail::UnwrapOr<typename std::decay<Fallback>::type>>
  707. UnwrapOr unwrapOr(Fallback&& fallback) {
  708. return UnwrapOr(std::forward<Fallback>(fallback));
  709. }
  710. } // namespace gen
  711. } // namespace folly
  712. #include <folly/gen/Base-inl.h>