summaryrefslogtreecommitdiff
path: root/Ix
diff options
context:
space:
mode:
authorKirk Shoop <kirk.shoop@microsoft.com>2013-02-07 01:11:48 -0800
committerKirk Shoop <kirk.shoop@microsoft.com>2013-02-07 01:11:48 -0800
commite6a9df4ff6a4e3e9ab9fc5dcea4137d6dcf324ab (patch)
tree82273c15c64f1829d9e0a1500c0f5757d66ae4f5 /Ix
parent8752ac371150f7124f2648002c6182cf10bdff60 (diff)
downloadRxCpp-e6a9df4ff6a4e3e9ab9fc5dcea4137d6dcf324ab.tar.gz
Get the CPP linq sample compiling on clang 4.1 (OSX)
Diffstat (limited to 'Ix')
-rw-r--r--Ix/CPP/samples/SampleCppLinq/SampleCppLinq.cpp8
-rw-r--r--Ix/CPP/src/cpplinq/linq.hpp21
-rw-r--r--Ix/CPP/src/cpplinq/linq_iterators.hpp8
-rw-r--r--Ix/CPP/src/cpplinq/util.hpp13
4 files changed, 36 insertions, 14 deletions
diff --git a/Ix/CPP/samples/SampleCppLinq/SampleCppLinq.cpp b/Ix/CPP/samples/SampleCppLinq/SampleCppLinq.cpp
index e459e4b..3e6483e 100644
--- a/Ix/CPP/samples/SampleCppLinq/SampleCppLinq.cpp
+++ b/Ix/CPP/samples/SampleCppLinq/SampleCppLinq.cpp
@@ -3,8 +3,6 @@
// SampleCppLinq.cpp : Defines the entry point for the console application.
//
-#include <cpplinq\linq.hpp>
-
#include <iostream>
#include <fstream>
#include <iomanip>
@@ -16,6 +14,8 @@
#include <algorithm>
#include <numeric>
+#include <cpplinq/linq.hpp>
+
using namespace std;
vector<string> load_data();
@@ -52,7 +52,7 @@ void run()
for (auto giter = data.begin(), end = data.end(); giter != end; ++giter)
{
- auto& g = *giter;
+ const auto& g = *giter;
cout << "arguments: " << g.key << endl;
@@ -63,7 +63,7 @@ void run()
for (auto giter = seq.begin(), end = seq.end(); giter != end; ++giter)
{
- auto& g = *giter;
+ const auto& g = *giter;
cout << g.key << ", ";
diff --git a/Ix/CPP/src/cpplinq/linq.hpp b/Ix/CPP/src/cpplinq/linq.hpp
index 1070331..7a7f6c2 100644
--- a/Ix/CPP/src/cpplinq/linq.hpp
+++ b/Ix/CPP/src/cpplinq/linq.hpp
@@ -149,6 +149,15 @@
#define LINQ_USE_RTTI 1
#endif
+#if defined(__clang__)
+#if __has_feature(cxx_rvalue_references)
+#define LINQ_USE_RVALUEREF 1
+#endif
+#if __has_feature(cxx_rtti)
+#define LINQ_USE_RTTI 1
+#endif
+#endif
+
// individual features
#include "util.hpp"
@@ -242,7 +251,7 @@ public:
template <class Predicate>
linq_driver< linq_where<Collection, Predicate> > where(Predicate p) const {
- return typename linq_where<Collection, Predicate>(c, std::move(p) );
+ return linq_where<Collection, Predicate>(c, std::move(p) );
}
@@ -266,7 +275,7 @@ public:
return std::accumulate(begin(), end(), initialValue, fn);
}
- bool any() const { return !empty(cur); }
+ bool any() const { auto cur = c.get_cursor(); return !cur.empty(); }
template <class Predicate>
bool any(Predicate p) const {
@@ -282,12 +291,16 @@ public:
// TODO: average
+#if !defined(__clang__)
+ // Clang complains that linq_driver is not complete until the closing brace
+ // so (linq_driver*)->select() cannot be resolved.
template <class U>
auto cast()
-> decltype(static_cast<linq_driver*>(0)->select(detail::cast_to<U>()))
{
return this->select(detail::cast_to<U>());
}
+#endif
// TODO: concat
@@ -295,12 +308,12 @@ public:
return std::find(begin(), end(), value) != end();
}
- typename std::iterator_traits<iterator>::distance_type count() const {
+ typename std::iterator_traits<iterator>::difference_type count() const {
return std::distance(begin(), end());
}
template <class Predicate>
- typename std::iterator_traits<iterator>::distance_type count(Predicate p) const {
+ typename std::iterator_traits<iterator>::difference_type count(Predicate p) const {
auto filtered = this->where(p);
return std::distance(begin(filtered), end(filtered));
}
diff --git a/Ix/CPP/src/cpplinq/linq_iterators.hpp b/Ix/CPP/src/cpplinq/linq_iterators.hpp
index ed267ec..a04b217 100644
--- a/Ix/CPP/src/cpplinq/linq_iterators.hpp
+++ b/Ix/CPP/src/cpplinq/linq_iterators.hpp
@@ -74,16 +74,16 @@ namespace cpplinq {
namespace util {
template <class Iter, class T>
typename std::iterator_traits<Iter>::pointer deref_iterator(const Iter& it) {
- return detail::deref_iterator(it, std::identity<typename std::iterator_traits<Iter>::reference>());
+ return deref_iterator(it, util::identity<typename std::iterator_traits<Iter>::reference>());
}
template <class Iter, class T>
- T* deref_iterator(const Iter& it, std::identity<T&>) {
+ T* deref_iterator(const Iter& it, util::identity<T&>) {
return &*it;
}
template <class Iter, class T>
- util::value_ptr<T> deref_iterator(const Iter& it, std::identity<T>) {
+ util::value_ptr<T> deref_iterator(const Iter& it, util::identity<T>) {
return util::value_ptr<T>(*it);
}
}
@@ -137,7 +137,7 @@ namespace cpplinq {
return cur->get();
}
- pointer operator->() const {
+ typename cursor_iterator::pointer operator->() const {
auto& v = **this;
return &v;
}
diff --git a/Ix/CPP/src/cpplinq/util.hpp b/Ix/CPP/src/cpplinq/util.hpp
index 6fb62ff..f1e5222 100644
--- a/Ix/CPP/src/cpplinq/util.hpp
+++ b/Ix/CPP/src/cpplinq/util.hpp
@@ -104,17 +104,26 @@ namespace cpplinq { namespace util {
detail::instance<A2>(),
detail::instance<A3>())) type;
};
-#else
+#elif defined(_MSC_VER)
template <class T>
struct result_of<T> : std::tr1::result_of<T> {};
+#else
+ using std::result_of;
#endif
+ template<class Type>
+ struct identity
+ {
+ typedef Type type;
+ Type operator()(const Type& left) const {return left;}
+ };
+
// faux pointer proxy for iterators that dereference to a value rather than reference, such as selectors
template <class T>
struct value_ptr
{
T value;
- value_ptr(const T& pvalue) : value(value)
+ value_ptr(const T& value) : value(value)
{}
value_ptr(const T* pvalue) : value(*pvalue)
{}