#include "folly/Portability.h"
#include "folly/FBString.h"
-#include <glog/logging.h>
#include <algorithm>
+#include <boost/operators.hpp>
#include <cstring>
+#include <glog/logging.h>
#include <iosfwd>
-#include <string>
#include <stdexcept>
+#include <string>
#include <type_traits>
-#include <boost/operators.hpp>
// libc++ doesn't provide this header
#if !FOLLY_USE_LIBCPP
// Works only for Range<const char*>
/* implicit */ Range(const std::string& str)
: b_(str.data()), e_(b_ + str.size()) {}
+
// Works only for Range<const char*>
Range(const std::string& str, std::string::size_type startFrom) {
if (UNLIKELY(startFrom > str.size())) {
* Create a range from two iterators, with type deduction.
*/
template <class Iter>
-Range<Iter> makeRange(Iter first, Iter last) {
+Range<Iter> range(Iter first, Iter last) {
return Range<Iter>(first, last);
}
+/*
+ * Creates a range to reference the contents of a contiguous-storage container.
+ */
+// Use pointers for types with '.data()' member
+template <class Collection,
+ class T = typename std::remove_pointer<
+ decltype(std::declval<Collection>().data())>::type>
+Range<T*> range(Collection&& v) {
+ return Range<T*>(v.data(), v.data() + v.size());
+}
+
+template <class T, size_t n>
+Range<T*> range(T (&array)[n]) {
+ return Range<T*>(array, array + n);
+}
+
typedef Range<const char*> StringPiece;
typedef Range<char*> MutableStringPiece;
typedef Range<const unsigned char*> ByteRange;
#include "folly/Benchmark.h"
#include "folly/gen/Base.h"
-using namespace folly;
using namespace folly::gen;
+using folly::fbstring;
using std::pair;
using std::set;
using std::vector;
int main(int argc, char *argv[]) {
google::ParseCommandLineFlags(&argc, &argv, true);
- runBenchmarks();
+ folly::runBenchmarks();
return 0;
}
TEST(Gen, Range) {
// cover the fenceposts of the loop unrolling
for (int n = 1; n < 100; ++n) {
- EXPECT_EQ(range(0, n) | count, n);
+ EXPECT_EQ(gen::range(0, n) | count, n);
}
}
TEST(Gen, FromIterators) {
vector<int> source {2, 3, 5, 7, 11};
- auto gen = from(makeRange(source.begin() + 1, source.end() - 1));
+ auto gen = from(folly::range(source.begin() + 1, source.end() - 1));
EXPECT_EQ(3 * 5 * 7, gen | product);
}
EXPECT_FALSE(seq(0, 10) | any([](int i) { return i == 11; }));
EXPECT_TRUE(from({1}) | any);
- EXPECT_FALSE(range(0, 0) | any);
+ EXPECT_FALSE(gen::range(0, 0) | any);
EXPECT_FALSE(from({1}) | take(0) | any);
}
indent();
newline();
(*this)(a[0]);
- for (auto& val : makeRange(boost::next(a.begin()), a.end())) {
+ for (auto& val : range(boost::next(a.begin()), a.end())) {
out_ += ',';
newline();
(*this)(val);
auto expPart = in.skipDigits();
end = expPart.end();
}
- auto fullNum = makeRange(integral.begin(), end);
+ auto fullNum = range(integral.begin(), end);
auto val = to<double>(fullNum);
return val;
{
vector<int> vi { 2, 3, 4, 5 };
- auto c = std::make_pair(makeRange(vi.begin(), vi.begin() + 3),
- makeRange(vi.begin() + 1, vi.begin() + 4));
+ auto c = std::make_pair(range(vi.begin(), vi.begin() + 3),
+ range(vi.begin() + 1, vi.begin() + 4));
dynamic d = { { 2, 3, 4 }, { 3, 4, 5 } };
EXPECT_EQ(d, toDynamic(c));
}
#include "folly/Range.h"
-#include <limits>
+#include <array>
+#include <boost/range/concepts.hpp>
#include <cstdlib>
-#include <string>
+#include <gtest/gtest.h>
#include <iterator>
+#include <limits>
+#include <string>
#include <sys/mman.h>
-#include <boost/range/concepts.hpp>
-#include <gtest/gtest.h>
+#include <vector>
namespace folly { namespace detail {
MutableByteRange r2(sp);
}
}
+
+template<class C>
+void testRangeFunc(C&& x, size_t n) {
+ const auto& cx = x;
+ // type, conversion checks
+ Range<int*> r1 = range(std::forward<C>(x));
+ Range<const int*> r2 = range(std::forward<C>(x));
+ Range<const int*> r3 = range(cx);
+ Range<const int*> r5 = range(std::move(cx));
+ EXPECT_EQ(r1.begin(), &x[0]);
+ EXPECT_EQ(r1.end(), &x[n]);
+ EXPECT_EQ(n, r1.size());
+ EXPECT_EQ(n, r2.size());
+ EXPECT_EQ(n, r3.size());
+ EXPECT_EQ(n, r5.size());
+}
+
+TEST(RangeFunc, Vector) {
+ std::vector<int> x;
+ testRangeFunc(x, 0);
+ x.push_back(2);
+ testRangeFunc(x, 1);
+ testRangeFunc(std::vector<int>{1, 2}, 2);
+}
+
+TEST(RangeFunc, Array) {
+ std::array<int, 3> x;
+ testRangeFunc(x, 3);
+}
+
+TEST(RangeFunc, CArray) {
+ int x[] {1, 2, 3, 4};
+ testRangeFunc(x, 4);
+}