void foreach(Body&&) const {}
};
-template<class Value>
-class Just : public GenImpl<const Value&, Just<Value>> {
+template <class Value>
+class SingleReference : public GenImpl<Value&, SingleReference<Value>> {
+ static_assert(!std::is_reference<Value>::value,
+ "SingleReference requires non-ref types");
+ Value* ptr_;
+ public:
+ explicit SingleReference(Value* ptr) : ptr_(ptr){}
+
+ template <class Handler>
+ bool apply(Handler&& handler) const {
+ return handler(*ptr_);
+ }
+
+ template <class Body>
+ void foreach(Body&& body) const {
+ body(*ptr_);
+ }
+};
+
+template <class Value>
+class SingleCopy : public GenImpl<const Value&, SingleCopy<Value>> {
static_assert(!std::is_reference<Value>::value,
- "Just requires non-ref types");
- const Value value_;
+ "SingleCopy requires non-ref types");
+ Value value_;
public:
- explicit Just(Value value) : value_(std::forward<Value>(value)) {}
+ explicit SingleCopy(Value value) : value_(std::forward<Value>(value)) {}
template <class Handler>
bool apply(Handler&& handler) const {
class Empty;
template<class Value>
-class Just;
+class SingleReference;
+
+template<class Value>
+class SingleCopy;
/*
* Operators
/*
* 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 = detail::SingleReference<Value>>
+Just just(Value& value) {
+ return Just(&value);
+}
+
+template <class Value, class Just = detail::SingleReference<const Value>>
+Just just(const Value& value) {
+ return Just(&value);
+}
+
+template <class Value,
+ class Just = detail::SingleCopy<typename std::decay<Value>::type>>
+Just just(Value&& value) {
+ return Just(std::move(value));
}
/*
class Source,
class Result =
decltype(std::declval<Sink>().compose(std::declval<Source>())),
- class Just = Just<typename std::decay<Result>::type>>
+ class Just = SingleCopy<typename std::decay<Result>::type>>
Just compose(const GenImpl<Value, Source>& source) const {
return Just(source | sink_);
}
EXPECT_EQ(expected, actual);
}
+TEST(Gen, Just) {
+ {
+ int x = 3;
+ auto j = just(x);
+ EXPECT_EQ(&x, j | mapped([](const int& v) { return &v; }) | first);
+ x = 4;
+ EXPECT_EQ(4, j | first);
+ }
+ {
+ int x = 3;
+ const int& cx = x;
+ auto j = just(cx);
+ EXPECT_EQ(&x, j | mapped([](const int& v) { return &v; }) | first);
+ x = 5;
+ EXPECT_EQ(5, j | first);
+ }
+ {
+ int x = 3;
+ auto j = just(std::move(x));
+ EXPECT_NE(&x, j | mapped([](const int& v) { return &v; }) | first);
+ x = 5;
+ EXPECT_EQ(3, j | first);
+ }
+}
+
int main(int argc, char *argv[]) {
testing::InitGoogleTest(&argc, argv);
gflags::ParseCommandLineFlags(&argc, &argv, true);