From e6a9df4ff6a4e3e9ab9fc5dcea4137d6dcf324ab Mon Sep 17 00:00:00 2001 From: Kirk Shoop Date: Thu, 7 Feb 2013 01:11:48 -0800 Subject: Get the CPP linq sample compiling on clang 4.1 (OSX) --- Ix/CPP/samples/SampleCppLinq/SampleCppLinq.cpp | 8 ++++---- Ix/CPP/src/cpplinq/linq.hpp | 21 +++++++++++++++++---- Ix/CPP/src/cpplinq/linq_iterators.hpp | 8 ++++---- Ix/CPP/src/cpplinq/util.hpp | 13 +++++++++++-- 4 files changed, 36 insertions(+), 14 deletions(-) (limited to 'Ix') 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 - #include #include #include @@ -16,6 +14,8 @@ #include #include +#include + using namespace std; vector 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 linq_driver< linq_where > where(Predicate p) const { - return typename linq_where(c, std::move(p) ); + return linq_where(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 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 auto cast() -> decltype(static_cast(0)->select(detail::cast_to())) { return this->select(detail::cast_to()); } +#endif // TODO: concat @@ -295,12 +308,12 @@ public: return std::find(begin(), end(), value) != end(); } - typename std::iterator_traits::distance_type count() const { + typename std::iterator_traits::difference_type count() const { return std::distance(begin(), end()); } template - typename std::iterator_traits::distance_type count(Predicate p) const { + typename std::iterator_traits::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 typename std::iterator_traits::pointer deref_iterator(const Iter& it) { - return detail::deref_iterator(it, std::identity::reference>()); + return deref_iterator(it, util::identity::reference>()); } template - T* deref_iterator(const Iter& it, std::identity) { + T* deref_iterator(const Iter& it, util::identity) { return &*it; } template - util::value_ptr deref_iterator(const Iter& it, std::identity) { + util::value_ptr deref_iterator(const Iter& it, util::identity) { return util::value_ptr(*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(), detail::instance())) type; }; -#else +#elif defined(_MSC_VER) template struct result_of : std::tr1::result_of {}; +#else + using std::result_of; #endif + template + 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 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) {} -- cgit v1.2.3