Fix default arguments for orderBy()
[folly.git] / folly / gen / Base.h
index 06cc0e3c89e1f786e9987a67b17e8f1b6d25b3a7..093ee007ed5b9f153e59b1e68344ef34f47fe5fb 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2014 Facebook, Inc.
+ * Copyright 2015 Facebook, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 #include <vector>
 #include <unordered_set>
 
-#include "folly/Range.h"
-#include "folly/Optional.h"
-#include "folly/Conv.h"
-#include "folly/gen/Core.h"
+#include <folly/Range.h>
+#include <folly/Optional.h>
+#include <folly/Conv.h>
+#include <folly/gen/Core.h>
 
 /**
  * Generator-based Sequence Comprehensions in C++, akin to C#'s LINQ
@@ -136,6 +136,10 @@ class MemberFunction {
   Result operator()(Class& x) const {
     return (x.*member_)();
   }
+
+  Result operator()(Class* x) const {
+    return (x->*member_)();
+  }
 };
 
 template<class Class,
@@ -153,6 +157,10 @@ class ConstMemberFunction{
   Result operator()(const Class& x) const {
     return (x.*member_)();
   }
+
+  Result operator()(const Class* x) const {
+    return (x->*member_)();
+  }
 };
 
 template<class Class,
@@ -171,10 +179,18 @@ class Field {
     return x.*field_;
   }
 
+  const FieldType& operator()(const Class* x) const {
+    return x->*field_;
+  }
+
   FieldType& operator()(Class& x) const {
     return x.*field_;
   }
 
+  FieldType& operator()(Class* x) const {
+    return x->*field_;
+  }
+
   FieldType&& operator()(Class&& x) const {
     return std::move(x.*field_);
   }
@@ -256,9 +272,24 @@ template<class Value,
          class Container = std::vector<typename std::decay<Value>::type>>
 class CopiedSource;
 
-template<class Value, bool endless = false, bool endInclusive = false>
+template<class Value, class SequenceImpl>
 class Sequence;
 
+template <class Value>
+class RangeImpl;
+
+template <class Value, class Distance>
+class RangeWithStepImpl;
+
+template <class Value>
+class SeqImpl;
+
+template <class Value, class Distance>
+class SeqWithStepImpl;
+
+template <class Value>
+class InfiniteImpl;
+
 template<class Value, class Source>
 class Yield;
 
@@ -266,7 +297,10 @@ template<class Value>
 class Empty;
 
 template<class Value>
-class Just;
+class SingleReference;
+
+template<class Value>
+class SingleCopy;
 
 /*
  * Operators
@@ -282,6 +316,8 @@ class Until;
 
 class Take;
 
+class Stride;
+
 template<class Rand>
 class Sample;
 
@@ -309,6 +345,8 @@ class Batch;
 
 class Dereference;
 
+class Indirect;
+
 /*
  * Sinks
  */
@@ -396,21 +434,36 @@ From from(Container&& source) {
   return From(std::move(source));
 }
 
-template<class Value, class Gen = detail::Sequence<Value, false, false>>
+template<class Value, class Impl = detail::RangeImpl<Value>,
+         class Gen = detail::Sequence<Value, Impl>>
 Gen range(Value begin, Value end) {
-  return Gen(begin, end);
+  return Gen{std::move(begin), Impl{std::move(end)}};
 }
 
-template<class Value,
-         class Gen = detail::Sequence<Value, false, true>>
+template<class Value, class Distance,
+         class Impl = detail::RangeWithStepImpl<Value, Distance>,
+         class Gen = detail::Sequence<Value, Impl>>
+Gen range(Value begin, Value end, Distance step) {
+  return Gen{std::move(begin), Impl{std::move(end), std::move(step)}};
+}
+
+template<class Value, class Impl = detail::SeqImpl<Value>,
+         class Gen = detail::Sequence<Value, Impl>>
 Gen seq(Value first, Value last) {
-  return Gen(first, last);
+  return Gen{std::move(first), Impl{std::move(last)}};
 }
 
-template<class Value,
-         class Gen = detail::Sequence<Value, true>>
-Gen seq(Value begin) {
-  return Gen(begin);
+template<class Value, class Distance,
+         class Impl = detail::SeqWithStepImpl<Value, Distance>,
+         class Gen = detail::Sequence<Value, Impl>>
+Gen seq(Value first, Value last, Distance step) {
+  return Gen{std::move(first), Impl{std::move(last), std::move(step)}};
+}
+
+template<class Value, class Impl = detail::InfiniteImpl<Value>,
+         class Gen = detail::Sequence<Value, Impl>>
+Gen seq(Value first) {
+  return Gen{std::move(first), Impl{}};
 }
 
 template<class Value,
@@ -432,14 +485,19 @@ Yield generator(Source&& source) {
 /*
  * empty() - for producing empty sequences.
  */
-template<class Value>
+template <class Value>
 detail::Empty<Value> empty() {
   return {};
 }
 
-template<class Value>
-detail::Just<Value> just(Value value) {
-  return detail::Just<Value>(std::move(value));
+template <
+    class Value,
+    class Just = typename std::conditional<
+        std::is_reference<Value>::value,
+        detail::SingleReference<typename std::remove_reference<Value>::type>,
+        detail::SingleCopy<Value>>::type>
+Just just(Value&& value) {
+  return Just(std::forward<Value>(value));
 }
 
 /*
@@ -489,12 +547,29 @@ enum MemberType {
   Mutable
 };
 
+/**
+ * These exist because MSVC has problems with expression SFINAE in templates
+ * assignment and comparisons don't work properly without being pulled out
+ * of the template declaration
+ */
+template <MemberType Constness> struct ExprIsConst {
+  enum {
+    value = Constness == Const
+  };
+};
+
+template <MemberType Constness> struct ExprIsMutable {
+  enum {
+    value = Constness == Mutable
+  };
+};
+
 template<MemberType Constness = Const,
          class Class,
          class Return,
          class Mem = ConstMemberFunction<Class, Return>,
          class Map = detail::Map<Mem>>
-typename std::enable_if<Constness == Const, Map>::type
+typename std::enable_if<ExprIsConst<Constness>::value, Map>::type
 member(Return (Class::*member)() const) {
   return Map(Mem(member));
 }
@@ -504,7 +579,7 @@ template<MemberType Constness = Mutable,
          class Return,
          class Mem = MemberFunction<Class, Return>,
          class Map = detail::Map<Mem>>
-typename std::enable_if<Constness == Mutable, Map>::type
+typename std::enable_if<ExprIsMutable<Constness>::value, Map>::type
 member(Return (Class::*member)()) {
   return Map(Mem(member));
 }
@@ -550,24 +625,24 @@ Until until(Predicate pred = Predicate()) {
   return Until(std::move(pred));
 }
 
-template<class Selector,
+template<class Selector = Identity,
          class Comparer = Less,
          class Order = detail::Order<Selector, Comparer>>
-Order orderBy(Selector selector = Identity(),
+Order orderBy(Selector selector = Selector(),
               Comparer comparer = Comparer()) {
   return Order(std::move(selector),
                std::move(comparer));
 }
 
-template<class Selector,
+template<class Selector = Identity,
          class Order = detail::Order<Selector, Greater>>
-Order orderByDescending(Selector selector = Identity()) {
+Order orderByDescending(Selector selector = Selector()) {
   return Order(std::move(selector));
 }
 
-template<class Selector,
+template<class Selector = Identity,
          class Distinct = detail::Distinct<Selector>>
-Distinct distinctBy(Selector selector = Identity()) {
+Distinct distinctBy(Selector selector = Selector()) {
   return Distinct(std::move(selector));
 }
 
@@ -663,6 +738,6 @@ GuardImpl guard(ErrorHandler&& handler) {
 
 }} // folly::gen
 
-#include "folly/gen/Base-inl.h"
+#include <folly/gen/Base-inl.h>
 
 #endif // FOLLY_GEN_BASE_H