diff options
author | Kirk Shoop <kirk.shoop@microsoft.com> | 2013-02-07 01:11:48 -0800 |
---|---|---|
committer | Kirk Shoop <kirk.shoop@microsoft.com> | 2013-02-07 01:11:48 -0800 |
commit | e6a9df4ff6a4e3e9ab9fc5dcea4137d6dcf324ab (patch) | |
tree | 82273c15c64f1829d9e0a1500c0f5757d66ae4f5 /Ix | |
parent | 8752ac371150f7124f2648002c6182cf10bdff60 (diff) | |
download | RxCpp-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.cpp | 8 | ||||
-rw-r--r-- | Ix/CPP/src/cpplinq/linq.hpp | 21 | ||||
-rw-r--r-- | Ix/CPP/src/cpplinq/linq_iterators.hpp | 8 | ||||
-rw-r--r-- | Ix/CPP/src/cpplinq/util.hpp | 13 |
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) {} |