summaryrefslogtreecommitdiff
path: root/Ix/CPP/src/cpplinq
diff options
context:
space:
mode:
Diffstat (limited to 'Ix/CPP/src/cpplinq')
-rw-r--r--Ix/CPP/src/cpplinq/linq.hpp584
-rw-r--r--Ix/CPP/src/cpplinq/linq_cursor.hpp342
-rw-r--r--Ix/CPP/src/cpplinq/linq_groupby.hpp195
-rw-r--r--Ix/CPP/src/cpplinq/linq_iterators.hpp196
-rw-r--r--Ix/CPP/src/cpplinq/linq_last.hpp85
-rw-r--r--Ix/CPP/src/cpplinq/linq_select.hpp54
-rw-r--r--Ix/CPP/src/cpplinq/linq_selectmany.hpp164
-rw-r--r--Ix/CPP/src/cpplinq/linq_skip.hpp37
-rw-r--r--Ix/CPP/src/cpplinq/linq_take.hpp98
-rw-r--r--Ix/CPP/src/cpplinq/linq_where.hpp69
-rw-r--r--Ix/CPP/src/cpplinq/util.hpp232
11 files changed, 0 insertions, 2056 deletions
diff --git a/Ix/CPP/src/cpplinq/linq.hpp b/Ix/CPP/src/cpplinq/linq.hpp
deleted file mode 100644
index 6552f79..0000000
--- a/Ix/CPP/src/cpplinq/linq.hpp
+++ /dev/null
@@ -1,584 +0,0 @@
-// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
-
-///
-/// namespace cpplinq
-/// -----------------
-///
-/// Defines a number of range-based composable operators for enumerating and modifying collections
-///
-/// The general design philosophy is to
-/// (1) emulate the composable query patterns introduced in C# Linq
-/// (2) preserve iterator category and writability where possible
-/// For instance, like C# Linq we have a select operator to project one sequence into a new one.
-/// Unlike Linq, invoking Select on a random access sequence will yield you a _random_ access sequence.
-///
-/// The general workflow begins with 'from()' which normally only takes a reference
-/// the the collection in question. However, from that point on, all operators function
-/// by value, so that the range can store any necessary state, rather than duplicating it
-/// onto iterator pairs.
-///
-/// In subsequent documentation, "powers" lists which powers that the operator attempts to preserve if
-/// available on on the input sequence. Some iterator powers may be skipped - in such a case, round down
-/// to the next supported power (e.g. if 'fwd' and 'rnd', an input of 'bidi' will round down to a 'fwd' result).
-///
-///
-///
-/// class linq_query
-/// ----------------
-///
-/// from(container&)
-/// ================
-/// - Result: Query
-///
-/// Construct a new query, from an lvalue reference to a collection. Does not copy the collection
-///
-///
-///
-/// from(iter, iter)
-/// ================
-/// - Result: Query
-///
-/// Construct a new query, from an iterator pair.
-///
-///
-///
-/// query.select(map)
-/// ==========================
-/// - Result: Query
-/// - Powers: input, forward, bidirectional, random access
-///
-/// For each element `x` in the input sequences, computes `map(x)` for the result sequence.
-///
-///
-///
-/// query.where(pred) -> query
-/// ==========================
-/// - Result: Query
-/// - Powers: input, forward, bidirectional
-///
-/// Each element `x` in the input appears in the output if `pred(x)` is true.
-///
-/// The expression `pred(x)` is evaluated only when moving iterators (op++, op--).
-/// Dereferencing (op*) does not invoke the predicate.
-///
-///
-///
-/// query.groupby(keymap [, keyequal])
-/// ====================================
-/// Result: Query of groups. Each group has a 'key' field, and is a query of elements from the input.
-/// Powers: forward
-///
-///
-///
-/// query.any([pred])
-/// =================
-/// - Result: bool
-///
-/// (No argument) Returns true if sequence is non-empty. Equivalent to `query.begin()!=query.end()`
-///
-/// (One argument) Returns true if the sequence contains any elements for which `pred(element)` is true.
-/// Equivalent to `query.where(pred).any()`.
-///
-///
-///
-/// query.all(pred)
-/// ===============
-/// - Result: bool
-///
-/// Returns true if `pred` holds for all elements in the sequence. Equivalent to `!query.any(std::not1(pred))`
-///
-///
-///
-/// query.take(n)
-/// =============
-/// - Result: query
-/// - Powers: input, forward, random access (not bidirectional)
-///
-/// Returns a sequence that contains up to `n` items from the original sequence.
-///
-///
-///
-/// query.skip(n)
-/// =============
-/// - Result: query
-/// - Powers: input, forward, random access (not bidirectional)
-///
-/// Returns a sequence that skips the first `n` items from the original sequence, or an empty sequence if
-/// fewer than `n` were available on input.
-///
-/// Note: begin() takes O(n) time when input iteration power is weaker than random access.
-///
-///
-///
-/// query.count([pred])
-/// ===================
-/// - Result: std::size_t
-///
-/// _TODO: should use inner container's iterator distance type instead._
-///
-/// (Zero-argument) Returns the number of elements in the range.
-/// Equivalent to `std::distance(query.begin(), query.end())`
-///
-/// (One-argument) Returns the number of elements for whicht `pred(element)` is true.
-/// Equivalent to `query.where(pred).count()`
-///
-
-
-
-#if !defined(CPPLINQ_LINQ_HPP)
-#define CPPLINQ_LINQ_HPP
-#pragma once
-
-#pragma push_macro("min")
-#pragma push_macro("max")
-#undef min
-#undef max
-
-#include <functional>
-#include <iterator>
-#include <algorithm>
-#include <numeric>
-#include <list>
-#include <map>
-#include <set>
-#include <memory>
-#include <utility>
-#include <type_traits>
-#include <vector>
-#include <cstddef>
-
-
-
-// some configuration macros
-#if _MSC_VER > 1600 || __cplusplus > 199711L
-#define LINQ_USE_RVALUEREF 1
-#endif
-
-#if (defined(_MSC_VER) && _CPPRTTI) || !defined(_MSC_VER)
-#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"
-#include "linq_cursor.hpp"
-#include "linq_iterators.hpp"
-#include "linq_select.hpp"
-#include "linq_take.hpp"
-#include "linq_skip.hpp"
-#include "linq_groupby.hpp"
-#include "linq_where.hpp"
-#include "linq_last.hpp"
-#include "linq_selectmany.hpp"
-
-
-
-
-namespace cpplinq
-{
-
-namespace detail
-{
- template<class Pred>
- struct not1_{
- Pred pred;
- not1_(Pred p) : pred(p)
- {}
- template<class T>
- bool operator()(const T& value)
- {
- return !pred(value);
- }
- };
- // note: VC2010's std::not1 doesn't support lambda expressions. provide our own.
- template<class Pred>
- not1_<Pred> not1(Pred p) { return not1_<Pred>(p); }
-}
-
-namespace detail {
- template <class U>
- struct cast_to {
- template <class T>
- U operator()(const T& value) const {
- return static_cast<U>(value);
- }
- };
-}
-
-template <class Collection>
-class linq_driver
-{
- typedef typename Collection::cursor::element_type
- element_type;
- typedef typename Collection::cursor::reference_type
- reference_type;
-public:
- typedef cursor_iterator<typename Collection::cursor>
- iterator;
-
- linq_driver(Collection c) : c(c) {}
-
-
- // -------------------- linq core methods --------------------
-
- template <class KeyFn>
- linq_driver< linq_groupby<Collection, KeyFn> > groupby(KeyFn fn)
- {
- return linq_groupby<Collection, KeyFn>(c, std::move(fn) );
- }
-
- // TODO: groupby(keyfn, eq)
-
- // TODO: join...
-
- template <class Selector>
- linq_driver< linq_select<Collection, Selector> > select(Selector sel) const {
- return linq_select<Collection, Selector>(c, std::move(sel) );
- }
-
- template <class Fn>
- linq_driver< linq_select_many<Collection, Fn, detail::default_select_many_selector> >
- select_many(Fn fn) const
- {
- return linq_select_many<Collection, Fn, detail::default_select_many_selector>(c, fn, detail::default_select_many_selector());
- }
-
- template <class Fn, class Fn2>
- linq_driver< linq_select_many<Collection, Fn, Fn2> > select_many(Fn fn, Fn2 fn2) const
- {
- return linq_select_many<Collection, Fn, Fn2>(c, fn, fn2);
- }
-
- template <class Predicate>
- linq_driver< linq_where<Collection, Predicate> > where(Predicate p) const {
- return linq_where<Collection, Predicate>(c, std::move(p) );
- }
-
-
- // -------------------- linq peripheral methods --------------------
-
- template <class Fn>
- element_type aggregate(Fn fn) const
- {
- auto it = begin();
- if (it == end()) {
- return element_type();
- }
-
- reference_type first = *it;
- return std::accumulate(++it, end(), first, fn);
- }
-
- template <class T, class Fn>
- T aggregate(T initialValue, Fn fn) const
- {
- return std::accumulate(begin(), end(), initialValue, fn);
- }
-
- bool any() const { auto cur = c.get_cursor(); return !cur.empty(); }
-
- template <class Predicate>
- bool any(Predicate p) const {
- auto it = std::find_if(begin(), end(), p);
- return it != end();
- }
-
- template <class Predicate>
- bool all(Predicate p) const {
- auto it = std::find_if(begin(), end(), detail::not1(p));
- return it == end();
- }
-
- // 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
-
- bool contains(const typename Collection::cursor::element_type& value) const {
- return std::find(begin(), end(), value) != end();
- }
-
- typename std::iterator_traits<iterator>::difference_type count() const {
- return std::distance(begin(), end());
- }
-
- template <class Predicate>
- typename std::iterator_traits<iterator>::difference_type count(Predicate p) const {
- auto filtered = this->where(p);
- return std::distance(begin(filtered), end(filtered));
- }
-
- // TODO: default_if_empty
-
- // TODO: distinct()
- // TODO: distinct(cmp)
-
- reference_type element_at(std::size_t ix) const {
- auto cur = c.get_cursor();
- while(ix && !cur.empty()) {
- cur.inc();
- --ix;
- }
- if (cur.empty()) { throw std::logic_error("index out of bounds"); }
- else { return cur.get(); }
- }
-
- element_type element_at_or_default(std::size_t ix) const {
- auto cur = c.get_cursor();
- while(ix && !cur.empty()) {
- cur.inc();
- -- ix;
- }
- if (cur.empty()) { return element_type(); }
- else { return cur.get(); }
- }
-
- bool empty() const {
- return !this->any();
- }
-
- // TODO: except(second)
- // TODO: except(second, eq)
-
- reference_type first() const {
- auto cur = c.get_cursor();
- if (cur.empty()) { throw std::logic_error("index out of bounds"); }
- else { return cur.get(); }
- }
-
- template <class Predicate>
- reference_type first(Predicate pred) const {
- auto cur = c.get_cursor();
- while (!cur.empty() && !pred(cur.get())) {
- cur.inc();
- }
- if (cur.empty()) { throw std::logic_error("index out of bounds"); }
- else { return cur.get(); }
- }
-
- element_type first_or_default() const {
- auto cur = c.get_cursor();
- if (cur.empty()) { return element_type(); }
- else { return cur.get(); }
- }
-
- template <class Predicate>
- element_type first_or_default(Predicate pred) const {
- auto cur = c.get_cursor();
- while (!cur.empty() && !pred(cur.get())) {
- cur.inc();
- }
- if (cur.empty()) { return element_type(); }
- else { return cur.get(); }
- }
-
- // TODO: intersect(second)
- // TODO: intersect(second, eq)
-
- // note: forward cursors and beyond can provide a clone, so we can refer to the element directly
- typename std::conditional<
- std::is_convertible<
- typename Collection::cursor::cursor_category,
- forward_cursor_tag>::value,
- reference_type,
- element_type>::type
- last() const
- {
- return linq_last_(c.get_cursor(), typename Collection::cursor::cursor_category());
- }
-
- template <class Predicate>
- reference_type last(Predicate pred) const
- {
- auto cur = c.where(pred).get_cursor();
- return linq_last_(cur, typename decltype(cur)::cursor_category());
- }
-
- element_type last_or_default() const
- {
- return linq_last_or_default_(c.get_cursor(), typename Collection::cursor::cursor_category());
- }
-
- template <class Predicate>
- element_type last_or_default(Predicate pred) const
- {
- auto cur = c.where(pred).get_cursor();
- return linq_last_or_default_(cur, typename decltype(cur)::cursor_category());
- }
-
- reference_type max() const
- {
- return max(std::less<element_type>());
- }
-
- template <class Compare>
- reference_type max(Compare less) const
- {
- auto it = std::max_element(begin(), end(), less);
- if (it == end())
- throw std::logic_error("max performed on empty range");
-
- return *it;
- }
-
- reference_type min() const
- {
- return min(std::less<element_type>());
- }
-
- template <class Compare>
- reference_type min(Compare less) const
- {
- auto it = std::min_element(begin(), end(), less);
- if (it == end())
- throw std::logic_error("max performed on empty range");
-
- return *it;
- }
-
- // TODO: order_by(sel)
- // TODO: order_by(sel, less)
- // TODO: order_by_descending(sel)
- // TODO: order_by_descending(sel, less)
-
- // TODO: sequence_equal(second)
- // TODO: sequence_equal(second, eq)
-
- // TODO: single / single_or_default
-
- linq_driver<linq_skip<Collection>> skip(std::size_t n) const {
- return linq_skip<Collection>(c, n);
- }
-
- // TODO: skip_while(pred)
-
- template<typename ITEM = element_type>
- typename std::enable_if<std::is_default_constructible<ITEM>::value, ITEM>::type sum() const {
- ITEM seed{};
- return sum(seed);
- }
-
- element_type sum(element_type seed) const {
- return std::accumulate(begin(), end(), seed);
- }
-
- template <typename Selector, typename Result = typename std::result_of<Selector(element_type)>::type>
- typename std::enable_if<std::is_default_constructible<Result>::value, Result>::type sum(Selector sel) const {
- return from(begin(), end()).select(sel).sum();
- }
-
- template <typename Selector, typename Result = typename std::result_of<Selector(element_type)>::type>
- Result sum(Selector sel, Result seed) const {
- return from(begin(), end()).select(sel).sum(seed);
- }
-
- linq_driver<linq_take<Collection>> take(std::size_t n) const {
- return linq_take<Collection>(c, n);
- }
-
- // TODO: take_while
-
- // TODO: then_by / then_by_descending ?
-
- // TODO: to_...
-
- // TODO: union(second)
- // TODO: union(eq)
-
- // TODO: zip
-
- // -------------------- conversion methods --------------------
-
- std::vector<typename Collection::cursor::element_type> to_vector() const
- {
- return std::vector<typename Collection::cursor::element_type>(begin(), end());
- }
-
- std::list<typename Collection::cursor::element_type> to_list() const
- {
- return std::list<typename Collection::cursor::element_type>(begin(), end());
- }
-
- std::set<typename Collection::cursor::element_type> to_set() const
- {
- return std::set<typename Collection::cursor::element_type>(begin(), end());
- }
-
- // -------------------- container/range methods --------------------
-
- iterator begin() const { auto cur = c.get_cursor(); return !cur.empty() ? iterator(cur) : iterator(); }
- iterator end() const { return iterator(); }
- linq_driver& operator=(const linq_driver& other) { c = other.c; return *this; }
- template <class TC2>
- linq_driver& operator=(const linq_driver<TC2>& other) { c = other.c; return *this; }
-
- typename std::iterator_traits<iterator>::reference
- operator[](std::size_t ix) const {
- return *(begin()+=ix);
- }
-
- // -------------------- collection methods (leaky abstraction) --------------------
-
- typedef typename Collection::cursor cursor;
- cursor get_cursor() { return c.get_cursor(); }
-
- linq_driver< dynamic_collection<typename Collection::cursor::reference_type> >
- late_bind() const
- {
- return dynamic_collection<typename Collection::cursor::reference_type>(c);
- }
-
-private:
- Collection c;
-};
-
-// TODO: should probably use reference-wrapper instead?
-template <class TContainer>
-linq_driver<iter_cursor<typename util::container_traits<TContainer>::iterator>> from(TContainer& c)
-{
- auto cur = iter_cursor<typename util::container_traits<TContainer>::iterator>(std::begin(c), std::end(c));
- return cur;
-}
-template <class T>
-const linq_driver<T>& from(const linq_driver<T>& c)
-{
- return c;
-}
-template <class Iter>
-linq_driver<iter_cursor<Iter>> from(Iter start, Iter finish)
-{
- return iter_cursor<Iter>(start, finish);
-}
-
-template <class TContainer>
-linq_driver<TContainer> from_value(const TContainer& c)
-{
- return linq_driver<TContainer>(c);
-}
-
-}
-
-#pragma pop_macro("min")
-#pragma pop_macro("max")
-
-#endif // defined(CPPLINQ_LINQ_HPP)
-
diff --git a/Ix/CPP/src/cpplinq/linq_cursor.hpp b/Ix/CPP/src/cpplinq/linq_cursor.hpp
deleted file mode 100644
index 4c5f5b5..0000000
--- a/Ix/CPP/src/cpplinq/linq_cursor.hpp
+++ /dev/null
@@ -1,342 +0,0 @@
-// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
-
-#if !defined(CPPLINQ_LINQ_CURSOR_HPP)
-#define CPPLINQ_LINQ_CURSOR_HPP
-#pragma once
-
-#include <cstddef>
-
-/// cursors
-/// ----------
-/// It should be noted that CppLinq uses a slightly different iterator concept, one where iterators
-/// know their extents. This sacrificed some generality, but it adds convenience and improves
-/// some performance in some cases. Notably, captures need only be stored once instead of twice in
-/// most use cases.
-///
-/// Cursors and Ranges are always classes.
-///
-/// To get a cursor from a range:
-///
-/// get_cursor(range) -> cur
-///
-/// Unlike boost ranges, CppLinq cursors are mutated directly, and may "shed state" as they are
-/// mutated. For example, a GroupBy range will drop references to earlier groups, possibly
-/// permitting freeing them.
-///
-/// Onepass cursor
-/// ===========
-/// - empty(cur) -> bool : at end of sequence
-/// - inc(cur)
-/// - get(cur) -> T
-/// - copy ctor : duplicate reference to seek position
-///
-/// Forward cursor
-/// =============
-/// - copy ctor : true duplicate of seek position
-///
-/// Bidirectional cursor
-/// ====================
-/// - forget() : notes the current element as the new 'begin' point
-/// - atbegin(cur) -> bool
-/// - dec(cur)
-///
-/// Random access cursor
-/// ====================
-/// - skip(cur, n)
-/// - position(cur) -> n
-/// - size(cur) -> n
-/// - truncate(n) : keep only n more elements
-///
-/// As well, cursors must define the appropriate type/typedefs:
-/// - cursor_category :: { onepass_cursor_tag, forward_cursor_tag, bidirectional_cursor_tag, random_access_cursor_tag }
-/// - element_type
-/// - reference_type : if writable, element_type& or such. else, == element_type
-/// -
-
-
-
-namespace cpplinq {
-
- // used to identify cursor-based collections
- struct collection_tag {};
-
- struct onepass_cursor_tag {};
- struct forward_cursor_tag : onepass_cursor_tag {};
- struct bidirectional_cursor_tag : forward_cursor_tag {};
- struct random_access_cursor_tag : bidirectional_cursor_tag {};
-
- struct noread_cursor_tag {}; // TODO: remove if not used
- struct readonly_cursor_tag : noread_cursor_tag {};
- struct readwrite_cursor_tag : readonly_cursor_tag {};
-
-
-
- // standard cursor adaptors
-
- namespace util
- {
- namespace detail
- {
- template <std::size_t n> struct type_to_size { char value[n]; };
-
- type_to_size<1> get_category_from_iterator(std::input_iterator_tag);
- type_to_size<2> get_category_from_iterator(std::forward_iterator_tag);
- type_to_size<3> get_category_from_iterator(std::bidirectional_iterator_tag);
- type_to_size<4> get_category_from_iterator(std::random_access_iterator_tag);
- }
-
- template <std::size_t>
- struct iter_to_cursor_category_;
-
- template <class Iter>
- struct iter_to_cursor_category
- {
- static const std::size_t catIx = sizeof(detail::get_category_from_iterator(typename std::iterator_traits<Iter>::iterator_category()) /*.value*/ );
- typedef typename iter_to_cursor_category_<catIx>::type type;
- };
-
- template <> struct iter_to_cursor_category_<1> { typedef onepass_cursor_tag type; };
- template <> struct iter_to_cursor_category_<2> { typedef forward_cursor_tag type; };
- template <> struct iter_to_cursor_category_<3> { typedef bidirectional_cursor_tag type; };
- template <> struct iter_to_cursor_category_<4> { typedef random_access_cursor_tag type; };
-
-
- // Note: returns false if no partial order exists between two
- // particular iterator categories, such as with some of the boost categories
- template <class Cat1, class Cat2>
- struct less_or_equal_cursor_category
- {
- private:
- typedef char yes;
- typedef struct { char c1,c2; } no;
- static yes invoke(Cat1);
- static no invoke(...);
- public:
- enum { value = (sizeof(invoke(Cat2())) == sizeof(yes)) };
- };
-
- // Return the weaker of the two iterator categories. Make sure
- // a non-standard category is in the second argument position, as
- // this metafunction will default to the first value if the order is undefined
- template <class Cat1, class Cat2, class Cat3 = void>
- struct min_cursor_category : min_cursor_category<typename min_cursor_category<Cat1, Cat2>::type, Cat3>
- {
- };
-
- template <class Cat1, class Cat2>
- struct min_cursor_category<Cat1, Cat2>
- : std::conditional<
- less_or_equal_cursor_category<Cat2, Cat1>::value,
- Cat2,
- Cat1>
- {
- };
-
- template <class Collection>
- struct cursor_type {
- typedef decltype(cursor(*static_cast<Collection*>(0))) type;
- };
- }
-
- // simultaniously models a cursor and a cursor-collection
- template <class Iterator>
- class iter_cursor : collection_tag {
- public:
-
- typedef iter_cursor cursor;
-
- typedef typename std::remove_reference<typename std::iterator_traits<Iterator>::value_type>::type
- element_type;
- typedef typename std::iterator_traits<Iterator>::reference
- reference_type;
- typedef typename util::iter_to_cursor_category<Iterator>::type
- cursor_category;
-
- void forget() { start = current; }
- bool empty() const { return current == fin; }
- void inc() {
- if (current == fin)
- throw std::logic_error("inc past end");
- ++current;
- }
- typename std::iterator_traits<Iterator>::reference get() const { return *current; }
-
- bool atbegin() const { return current == start; }
- void dec() {
- if (current == start)
- throw std::logic_error("dec past begin");
- --current;
- }
-
- void skip(std::ptrdiff_t n) { current += n; }
- std::size_t size() { return fin-start; }
- void position() { return current-start; }
- void truncate(std::size_t n) {
- if (n > fin-current) {
- fin = current + n;
- }
- }
-
-
- iter_cursor(Iterator start, Iterator fin)
- : current(start)
- , start(start)
- , fin(std::move(fin))
- {
- }
-
- iter_cursor(Iterator start, Iterator fin, Iterator current)
- : current(std::move(current))
- , start(std::move(start))
- , fin(std::move(fin))
- {
- }
-
- iter_cursor get_cursor() const { return *this; }
-
- private:
- Iterator current;
- Iterator start, fin;
- };
-
-
- template <class T>
- struct cursor_interface
- {
- virtual bool empty() const = 0;
- virtual void inc() = 0;
- virtual cursor_interface* copy() const = 0;
-
- virtual T get() const = 0;
-
- virtual ~cursor_interface() {}
- };
-
- template <class T>
- class dynamic_cursor : collection_tag
- {
- template <class Cur>
- struct instance : cursor_interface<T>
- {
- Cur innerCursor;
-
- instance(Cur cursor) : innerCursor(std::move(cursor))
- {
- }
- virtual bool empty() const
- {
- return innerCursor.empty();
- }
- virtual void inc()
- {
- innerCursor.inc();
- }
- virtual T get() const
- {
- return innerCursor.get();
- }
- virtual cursor_interface<T>* copy() const
- {
- return new instance(*this);
- }
- };
-
- std::unique_ptr<cursor_interface<T>> myCur;
-
- public:
- typedef forward_cursor_tag cursor_category; // TODO: not strictly true!
- typedef typename std::remove_reference<T>::type element_type;
- typedef T reference_type;
-
- dynamic_cursor() {}
-
- dynamic_cursor(const dynamic_cursor& other)
- : myCur(other.myCur ? other.myCur->copy() : nullptr)
- {
- }
-
- dynamic_cursor(dynamic_cursor&& other)
- : myCur(other.myCur.release())
- {
- }
-
- template <class Cursor>
- dynamic_cursor(Cursor cursor)
- : myCur(new instance<Cursor>(std::move(cursor)))
- {
- }
-
- template <class Iterator>
- dynamic_cursor(Iterator start, Iterator end)
- {
- *this = iter_cursor<Iterator>(start, end);
- }
-
- bool empty() const { return !myCur || myCur->empty(); }
- void inc() { myCur->inc(); }
- T get() const { return myCur->get(); }
-
- dynamic_cursor& operator=(dynamic_cursor other)
- {
- std::swap(myCur, other.myCur);
- return *this;
- }
- };
-
- template <class T>
- struct container_interface
- {
- virtual dynamic_cursor<T> get_cursor() const = 0;
- };
-
- template <class T>
- class dynamic_collection
- {
- std::shared_ptr< container_interface<T> > container;
-
- template <class Container>
- struct instance : container_interface<T>
- {
- Container c;
-
- instance(Container c) : c(c)
- {
- }
-
- dynamic_cursor<T> get_cursor() const
- {
- return c.get_cursor();
- }
- };
-
- public:
- typedef dynamic_cursor<T> cursor;
-
- dynamic_collection() {}
-
- dynamic_collection(const dynamic_collection& other)
- : container(other.container)
- {
- }
-
- // container or query
- template <class Container>
- dynamic_collection(Container c)
- : container(new instance<Container>(c))
- {
- }
-
- // container or query
- template <class Iterator>
- dynamic_collection(Iterator begin, Iterator end)
- : container(new instance< iter_cursor<Iterator> >(iter_cursor<Iterator>(begin, end)))
- {
- }
-
- dynamic_cursor<T> get_cursor() const {
- return container ? container->get_cursor() : dynamic_cursor<T>();
- }
- };
-}
-
-#endif // !defined(CPPLINQ_LINQ_CURSOR_HPP
diff --git a/Ix/CPP/src/cpplinq/linq_groupby.hpp b/Ix/CPP/src/cpplinq/linq_groupby.hpp
deleted file mode 100644
index c521e5e..0000000
--- a/Ix/CPP/src/cpplinq/linq_groupby.hpp
+++ /dev/null
@@ -1,195 +0,0 @@
-// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
-
-#if !defined(CPPLINQ_LINQ_GROUPBY_HPP)
-#define CPPLINQ_LINQ_GROUPBY_HPP
-#pragma once
-
-namespace cpplinq
-{
-
-template <class Iter, class Key>
-struct group
-{
- Key key;
- Iter start;
- Iter fin;
-
- typedef Iter iterator;
- typedef Iter const_iterator;
-
- group(){}
-
- group(const Key& key) : key(key)
- {
- }
-
- Iter begin() const { return start; }
- Iter end() const { return fin; }
-};
-
-struct default_equality
-{
- template <class T>
- bool operator()(const T& a, const T& b) const {
- return a == b;
- }
-};
-struct default_less
-{
- template<class T>
- bool operator()(const T& a, const T& b) const {
- return a < b;
- }
-};
-
-// progressively constructs grouping as user iterates over groups and elements
-// within each group. Performs this task by building a std::list of element
-// iterators with equal elements within each group.
-//
-// invariants:
-// - relative order of groups corresponds to relative order of each group's first
-// element, as they appeared in the input sequence.
-// - relative order of elements within a group correspond to relative order
-// as they appeared in the input sequence.
-//
-// requires:
-// Iter must be a forward iterator.
-template <class Collection, class KeyFn, class Compare = default_less>
-class linq_groupby
-{
- typedef typename Collection::cursor
- inner_cursor;
-
- typedef typename util::result_of<KeyFn(typename inner_cursor::element_type)>::type
- key_type;
-
- typedef std::list<typename inner_cursor::element_type>
- element_list_type;
-
- typedef group<typename element_list_type::iterator, key_type>
- group_type;
-
- typedef std::list<group_type>
- group_list_type;
-
-private:
- struct impl_t
- {
- // TODO: would be faster to use a chunked list, where
- // pointers are invalidated but iterators are not. Need
- // benchmarks first
-
- element_list_type elements;
- std::list<group_type> groups;
- std::map<key_type, group_type*, Compare> groupIndex;
-
-
-
- KeyFn keySelector;
- Compare comp;
-
- impl_t(inner_cursor cur,
- KeyFn keySelector,
- Compare comp = Compare())
- : keySelector(keySelector)
- , groupIndex(comp)
- {
- // TODO: make lazy
- insert_all(std::move(cur));
- }
-
- void insert_all(inner_cursor cur)
- {
- while(!cur.empty()) {
- insert(cur.get());
- cur.inc();
- }
- }
- void insert(typename inner_cursor::reference_type element)
- {
- key_type key = keySelector(element);
- auto groupPos = groupIndex.find(key);
- if(groupPos == groupIndex.end()) {
- // new group
- bool firstGroup = groups.empty();
-
- elements.push_back(element);
- if(!firstGroup) {
- // pop new element out of previous group
- --groups.back().fin;
- }
-
- // build new group
- groups.push_back(group_type(key));
- group_type& newGroup = groups.back();
-
- groupIndex.insert( std::make_pair(key, &newGroup) );
-
- newGroup.fin = elements.end();
- --(newGroup.start = newGroup.fin);
- } else {
- // add to existing group at end
- elements.insert(groupPos->second->end(), element);
- }
- }
- };
-
-public:
- struct cursor {
- typedef group_type
- element_type;
-
- typedef element_type
- reference_type;
-
- typedef forward_cursor_tag
- cursor_category;
-
- cursor(inner_cursor cur,
- KeyFn keyFn,
- Compare comp = Compare())
- {
- impl.reset(new impl_t(cur, keyFn, comp));
- inner = impl->groups.begin();
- fin = impl->groups.end();
- }
-
- void forget() { } // nop on forward-only cursors
- bool empty() const {
- return inner == fin;
- }
- void inc() {
- if (inner == fin) {
- throw std::logic_error("attempt to iterate past end of range");
- }
- ++inner;
- }
- reference_type get() const {
- return *inner;
- }
-
- private:
- std::shared_ptr<impl_t> impl;
- typename std::list<group_type>::iterator inner;
- typename std::list<group_type>::iterator fin;
- };
-
- linq_groupby(Collection c,
- KeyFn keyFn,
- Compare comp = Compare())
- : c(c), keyFn(keyFn), comp(comp)
- {
- }
-
- cursor get_cursor() const { return cursor(c.get_cursor(), keyFn, comp); }
-
-private:
- Collection c;
- KeyFn keyFn;
- Compare comp;
-};
-
-}
-
-#endif // !defined(CPPLINQ_LINQ_GROUPBY_HPP)
-
diff --git a/Ix/CPP/src/cpplinq/linq_iterators.hpp b/Ix/CPP/src/cpplinq/linq_iterators.hpp
deleted file mode 100644
index 3472281..0000000
--- a/Ix/CPP/src/cpplinq/linq_iterators.hpp
+++ /dev/null
@@ -1,196 +0,0 @@
-// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
-
-#if !defined(CPPLINQ_LINQ_ITERATORS_HPP)
-#define CPPLINQ_LINQ_ITERATORS_HPP
-#pragma once
-
-#include <cstddef>
-
-namespace cpplinq {
-
- // if a member, provides the straightforward implementation of various redundant operators. For example,
- // providing -> for any iterator providing *, and so forth.
- struct use_default_iterator_operators {};
-
- #define CPPLINQ_USE_DEFAULT_ITERATOR_OPERATORS \
- operator ::cpplinq::use_default_iterator_operators() const { return ::cpplinq::use_default_iterator_operators(); }
-
- template <class Iter>
- typename std::enable_if<
- std::is_convertible<Iter, use_default_iterator_operators>::value,
- Iter
- >::type
- operator+(const Iter& it, typename std::iterator_traits<Iter>::distance_type n) {
- return it += n;
- }
- template <class Iter>
- typename std::enable_if<
- std::is_convertible<Iter, use_default_iterator_operators>::value,
- Iter
- >::type
- operator-(const Iter& it, typename std::iterator_traits<Iter>::distance_type n) {
- return it -= n;
- }
- template <class Iter>
- typename std::enable_if<
- std::is_convertible<Iter, use_default_iterator_operators>::value,
- Iter
- >::type
- operator-=(const Iter& it, typename std::iterator_traits<Iter>::distance_type n) {
- return it += (-n);
- }
-
- template <class Iter>
- typename std::enable_if<
- std::is_convertible<Iter, use_default_iterator_operators>::value,
- bool
- >::type
- operator!=(const Iter& it, const Iter& it2) {
- return !(it == it2);
- }
- template <class Iter>
- typename std::enable_if<
- std::is_convertible<Iter, use_default_iterator_operators>::value,
- bool
- >::type
- operator>(const Iter& it, const Iter& it2) {
- return it2 < it;
- }
- template <class Iter>
- typename std::enable_if<
- std::is_convertible<Iter, use_default_iterator_operators>::value,
- bool
- >::type
- operator<=(const Iter& it, const Iter& it2) {
- return !(it2 < it);
- }
- template <class Iter>
- typename std::enable_if<
- std::is_convertible<Iter, use_default_iterator_operators>::value,
- bool
- >::type
- operator>=(const Iter& it, const Iter& it2) {
- return !(it < it2);
- }
-
- namespace util {
- template <class Iter, class T>
- typename std::iterator_traits<Iter>::pointer deref_iterator(const Iter& it) {
- return deref_iterator(it, util::identity<typename std::iterator_traits<Iter>::reference>());
- }
-
- template <class Iter, class 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, util::identity<T>) {
- return util::value_ptr<T>(*it);
- }
- }
-
-
- template <class Iter>
- class iter_range
- {
- Iter start, finish;
- public:
-
- CPPLINQ_USE_DEFAULT_ITERATOR_OPERATORS
-
- typedef Iter iterator;
- typedef typename iterator::value_type value_type;
-
- explicit iter_range(Iter start, Iter finish) : start(start), finish(finish) {}
- iterator begin() const { return start; }
- iterator end() const { return finish; }
- };
- template <class Iter>
- iter_range<Iter> make_range(Iter start, Iter finish) {
- return iter_range<Iter>(start, finish);
- }
-
- // decays into a onepass/forward iterator
- template <class Cursor>
- class cursor_iterator
- : public std::iterator<std::forward_iterator_tag,
- typename Cursor::element_type,
- std::ptrdiff_t,
- typename std::conditional<std::is_reference<typename Cursor::reference_type>::value,
- typename std::add_pointer<typename Cursor::element_type>::type,
- util::value_ptr<typename Cursor::element_type>>::type,
- typename Cursor::reference_type>
- {
- public:
- CPPLINQ_USE_DEFAULT_ITERATOR_OPERATORS;
-
- cursor_iterator(Cursor cur) : cur(cur) {
- }
-
- cursor_iterator() : cur() {
- }
-
- bool operator==(const cursor_iterator& other) const {
- return !cur && !other.cur;
- }
-
- typename Cursor::reference_type operator*() const {
- return cur->get();
- }
-
- typename cursor_iterator::pointer operator->() const {
- auto& v = **this;
- return &v;
- }
-
- cursor_iterator& operator++() {
- cur->inc();
-
- if (cur->empty()) { cur.reset(); }
- return *this;
- }
-
- cursor_iterator& operator+=(std::ptrdiff_t n) {
- cur->skip(n);
-
- if (cur->empty()) { cur.reset(); }
- return *this;
- }
-
-
-
- private:
- bool empty() const {
- !cur || cur->empty();
- }
-
- util::maybe<Cursor> cur;
- };
-
- template <class Container>
- class container_range
- {
- Container c;
-
- public:
- typedef cursor_iterator<typename Container::cursor> iterator;
-
- container_range(Container c) : c(c)
- {
- }
-
- iterator begin() const
- {
- return iterator(c.get_cursor());
- }
-
- iterator end() const
- {
- return iterator();
- }
- };
-
-}
-
-#endif
diff --git a/Ix/CPP/src/cpplinq/linq_last.hpp b/Ix/CPP/src/cpplinq/linq_last.hpp
deleted file mode 100644
index cb2bf76..0000000
--- a/Ix/CPP/src/cpplinq/linq_last.hpp
+++ /dev/null
@@ -1,85 +0,0 @@
-// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
-
-#if !defined(CPPLINQ_LINQ_LAST_HPP)
-#define CPPLINQ_LINQ_LAST_HPP
-#pragma once
-
-namespace cpplinq {
-
- template <class Cursor>
- typename Cursor::element_type
- linq_last_(Cursor c, onepass_cursor_tag)
- {
- if (c.empty()) { throw std::logic_error("last() out of bounds"); }
- typename Cursor::element_type elem = c.get();
- for(;;) {
- c.inc();
- if (c.empty()) break;
- elem = c.get();
- }
- return elem;
- }
-
- // TODO: bidirectional iterator in constant time
-
- template <class Cursor>
- typename Cursor::reference_type
- linq_last_(Cursor c, forward_cursor_tag)
- {
- if (c.empty()) { throw std::logic_error("last() out of bounds"); }
- Cursor best = c;
- for(;;) {
- c.inc();
- if (c.empty()) break;
- best = c;
- }
- return best.get();
- }
-
- template <class Cursor>
- typename Cursor::reference_type
- linq_last_(Cursor c, random_access_cursor_tag)
- {
- if (c.empty()) { throw std::logic_error("last() out of bounds"); }
- c.skip(c.size()-1);
- return c.get();
- }
-
- template <class Cursor>
- typename Cursor::element_type
- linq_last_or_default_(Cursor c, onepass_cursor_tag)
- {
- typename Cursor::element_type elem;
- while(!c.empty()) {
- elem = c.get();
- c.inc();
- }
- return elem;
- }
-
- template <class Cursor>
- typename Cursor::element_type
- linq_last_or_default_(Cursor c, forward_cursor_tag)
- {
- if (c.empty()) { throw std::logic_error("last() out of bounds"); }
- Cursor best = c;
- for(;;) {
- c.inc();
- if (c.empty()) break;
- best = c;
- }
- return best.get();
- }
-
- template <class Cursor>
- typename Cursor::element_type
- linq_last_or_default_(Cursor c, random_access_cursor_tag)
- {
- if (c.empty()) { return typename Cursor::element_type(); }
- c.skip(c.size()-1);
- return c.get();
- }
-
-}
-
-#endif // CPPLINQ_LINQ_LAST_HPP
diff --git a/Ix/CPP/src/cpplinq/linq_select.hpp b/Ix/CPP/src/cpplinq/linq_select.hpp
deleted file mode 100644
index d505284..0000000
--- a/Ix/CPP/src/cpplinq/linq_select.hpp
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
-
-#if !defined(CPPLINQ_LINQ_SELECT_HPP)
-#define CPPLINQ_LINQ_SELECT_HPP
-#pragma once
-
-#include <cstddef>
-
-namespace cpplinq
-{
- template <class Collection, class Selector>
- class linq_select
- {
- typedef typename Collection::cursor
- inner_cursor;
- public:
- struct cursor {
- typedef typename util::result_of<Selector(typename inner_cursor::element_type)>::type
- reference_type;
- typedef typename std::remove_reference<reference_type>::type
- element_type;
- typedef typename inner_cursor::cursor_category
- cursor_category;
-
- cursor(const inner_cursor& cur, Selector sel) : cur(cur), sel(std::move(sel)) {}
-
- void forget() { cur.forget(); }
- bool empty() const { return cur.empty(); }
- void inc() { cur.inc(); }
- reference_type get() const { return sel(cur.get()); }
-
- bool atbegin() const { return cur.atbegin(); }
- void dec() { cur.dec(); }
-
- void skip(std::size_t n) { cur.skip(n); }
- std::size_t position() const { return cur.position(); }
- std::size_t size() const { return cur.size(); }
- private:
- inner_cursor cur;
- Selector sel;
- };
-
- linq_select(const Collection& c, Selector sel) : c(c), sel(sel) {}
-
- cursor get_cursor() const { return cursor(c.get_cursor(), sel); }
-
- private:
- Collection c;
- Selector sel;
- };
-
-}
-
-#endif // defined(CPPLINQ_LINQ_SELECT_HPP)
diff --git a/Ix/CPP/src/cpplinq/linq_selectmany.hpp b/Ix/CPP/src/cpplinq/linq_selectmany.hpp
deleted file mode 100644
index 85f0d42..0000000
--- a/Ix/CPP/src/cpplinq/linq_selectmany.hpp
+++ /dev/null
@@ -1,164 +0,0 @@
-// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
-
-#pragma once
-
-#include "util.hpp"
-#include "linq_cursor.hpp"
-
-#include <type_traits>
-
-namespace cpplinq
-{
- namespace detail
- {
- struct default_select_many_selector
- {
- template <class T1, class T2>
- auto operator()(T1&& t1, T2&& t2) const
- -> decltype(std::forward<T2>(t2))
- {
- return std::forward<T2>(t2);
- }
- };
- }
-
- namespace detail
- {
- template <typename Fn, typename Arg>
- struct resolve_select_many_fn_return_type
- {
- typedef decltype(std::declval<Fn>()(std::declval<Arg>())) value;
- };
-
- template <typename TCol>
- struct value_collection_adapter
- {
- value_collection_adapter(const TCol& col)
- : _collection(col){}
-
- value_collection_adapter(const value_collection_adapter& src)
- : _collection(src._collection) {}
-
- value_collection_adapter(value_collection_adapter && src)
- : _collection(std::move(src._collection)) {}
-
- const TCol& get() const
- {
- return _collection;
- }
-
- TCol& get()
- {
- return _collection;
- }
-
- private:
- TCol _collection;
- };
-
- template<typename TCol>
- struct collection_store_type
- {
- typedef typename std::remove_reference<TCol>::type collection_type;
- typedef std::reference_wrapper<collection_type> reference_store_type;
- typedef value_collection_adapter<collection_type> value_store_type;
-
- typedef typename std::conditional<std::is_reference<TCol>::value, reference_store_type, value_store_type>::type store;
- };
- }
-
- // cur<T> -> (T -> cur<element_type>) -> cur<element_type>
- template <class Container1, class Fn, class Fn2>
- class linq_select_many
- {
- template <class T> static T instance(); // for type inference
-
- Container1 c1;
- Fn fn;
- Fn2 fn2;
-
- typedef typename Container1::cursor Cur1;
- typedef decltype(from(instance<Fn>()(instance<Cur1>().get()))) Container2;
- typedef typename Container2::cursor Cur2;
-
- typedef typename detail::resolve_select_many_fn_return_type<Fn, typename Cur1::element_type>::value inner_collection;
-
- public:
- class cursor
- {
- public:
- typedef typename util::min_cursor_category<typename Cur1::cursor_category,
- typename Cur2::cursor_category,
- forward_cursor_tag>::type
- cursor_category;
- typedef typename Cur2::reference_type reference_type;
- typedef typename Cur2::element_type element_type;
-
- typedef detail::collection_store_type<inner_collection> collection_store_type;
- typedef typename collection_store_type::store collection_store;
- typedef std::shared_ptr<collection_store> collection_store_ptr;
-
- private:
- // TODO: we need to lazy eval somehow, but this feels wrong.
- Cur1 cur1;
- dynamic_cursor<reference_type> cur2;
- Fn fn;
- Fn2 fn2;
- collection_store_ptr store;
-
- public:
- cursor(Cur1 cur1, const Fn& fn, const Fn2& fn2)
- : cur1(std::move(cur1)), fn(fn), fn2(fn2)
- {
- if (!cur1.empty())
- {
- store = std::make_shared<collection_store>(fn(cur1.get()));
- cur2 = from(store->get()).get_cursor();
- }
- }
-
- bool empty() const
- {
- return cur2.empty();
- }
-
- void inc()
- {
- cur2.inc();
- thunk();
- }
-
- reference_type get() const
- {
- return fn2(cur1.get(), cur2.get());
- }
-
- private:
- void thunk()
- {
- // refill cur2
- while (cur2.empty() && !cur1.empty()) {
- cur1.inc();
- if (cur1.empty())
- break;
-
- store = std::make_shared<collection_store>(fn(cur1.get()));
- cur2 = from(store->get()).get_cursor();
- }
- }
- };
-
- linq_select_many(Container1 c1, Fn fn, Fn2 fn2)
- : c1(std::move(c1)), fn(std::move(fn)), fn2(std::move(fn2))
- {
- }
-
- cursor get_cursor() const
- {
- return cursor(c1.get_cursor(), fn, fn2);
- }
- };
-}
-
-
-
diff --git a/Ix/CPP/src/cpplinq/linq_skip.hpp b/Ix/CPP/src/cpplinq/linq_skip.hpp
deleted file mode 100644
index 5b1624f..0000000
--- a/Ix/CPP/src/cpplinq/linq_skip.hpp
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
-
-#if !defined(CPPLINQ_LINQ_SKIP_HPP)
-#define CPPLINQ_LINQ_SKIP_HPP
-#pragma once
-
-#include <cstddef>
-
-namespace cpplinq
-{
- template <class Collection>
- struct linq_skip
- {
- public:
- typedef typename Collection::cursor cursor;
-
- linq_skip(const Collection& c, std::size_t n) : c(c), n(n) {}
-
- cursor get_cursor() const {
- std::size_t rem = n;
-
- auto cur = c.get_cursor();
- while(rem-- && !cur.empty()) {
- cur.inc();
- }
- cur.forget();
- return cur;
- }
-
- private:
- Collection c;
- std::size_t n;
- };
-}
-#endif // !defined(CPPLINQ_LINQ_SKIP_HPP)
-
-
diff --git a/Ix/CPP/src/cpplinq/linq_take.hpp b/Ix/CPP/src/cpplinq/linq_take.hpp
deleted file mode 100644
index a7093ef..0000000
--- a/Ix/CPP/src/cpplinq/linq_take.hpp
+++ /dev/null
@@ -1,98 +0,0 @@
-// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
-
-#if !defined(CPPLINQ_LINQ_TAKE_HPP)
-#define CPPLINQ_LINQ_TAKE_HPP
-#pragma once
-
-#include <cstddef>
-
-namespace cpplinq
-{
- template <class InnerCursor>
- struct linq_take_cursor
- {
- typedef typename InnerCursor::element_type element_type;
- typedef typename InnerCursor::reference_type reference_type;
- typedef typename InnerCursor::cursor_category cursor_category;
-
- linq_take_cursor(const InnerCursor& cur, std::size_t rem) : cur(cur), rem(rem) {}
-
- void forget() { cur.forget(); }
- bool empty() const { return cur.empty() || rem == 0; }
- void inc() { cur.inc(); --rem; }
- reference_type get() const { return cur.get(); }
-
- bool atbegin() const { return cur.atbegin(); }
- void dec() { cur.dec(); --rem; }
-
- void skip(std::size_t n) { cur.skip(n); rem -= n; }
- std::size_t position() const { return cur.position(); }
- std::size_t size() const { return cur.size(); }
-
- private:
- InnerCursor cur;
- std::size_t rem;
- };
-
- namespace detail {
- template <class Collection>
- linq_take_cursor<typename Collection::cursor>
- take_get_cursor_(
- const Collection& c,
- std::size_t n,
- onepass_cursor_tag
- )
- {
- return linq_take_cursor<typename Collection::cursor>(c.get_cursor(), n);
- }
-
- template <class Collection>
- typename Collection::cursor
- take_get_cursor_(
- const Collection& c,
- std::size_t n,
- random_access_cursor_tag
- )
- {
- auto cur = c.get_cursor();
- if (cur.size() > n) {
- cur.truncate(n);
- }
- return cur;
- }
- }
-
- template <class Collection>
- struct linq_take
- {
- typedef typename std::conditional<
- util::less_or_equal_cursor_category<
- random_access_cursor_tag,
- typename Collection::cursor::cursor_category>::value,
- typename Collection::cursor,
- linq_take_cursor<typename Collection::cursor>>::type
- cursor;
-
- linq_take(const Collection& c, std::size_t n) : c(c), n(n) {}
-
- cursor get_cursor() const {
- return detail::take_get_cursor_(c, n, typename Collection::cursor::cursor_category());
- }
-
- Collection c;
- std::size_t n;
- };
-
- template <class Collection>
- auto get_cursor(
- const linq_take<Collection>& take
- )
- -> decltype(get_cursor_(take, typename Collection::cursor::cursor_category()))
- {
- return get_cursor_(take, typename Collection::cursor::cursor_category());
- }
-
-
-}
-#endif // !defined(CPPLINQ_LINQ_TAKE_HPP)
-
diff --git a/Ix/CPP/src/cpplinq/linq_where.hpp b/Ix/CPP/src/cpplinq/linq_where.hpp
deleted file mode 100644
index 9b3d936..0000000
--- a/Ix/CPP/src/cpplinq/linq_where.hpp
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
-
-#if !defined(CPPLINQ_LINQ_WHERE_HPP)
-#define CPPLINQ_LINQ_WHERE_HPP
-#pragma once
-
-namespace cpplinq
-{
- template <class Collection, class Predicate>
- class linq_where
- {
- typedef typename Collection::cursor
- inner_cursor;
- public:
- struct cursor {
- typedef typename util::min_iterator_category<
- bidirectional_cursor_tag,
- typename inner_cursor::cursor_category>::type
- cursor_category;
- typedef typename inner_cursor::element_type
- element_type;
- typedef typename inner_cursor::reference_type
- reference_type;
-
- cursor(const inner_cursor& cur, const Predicate& p) : cur(cur), pred(p)
- {
- if (!cur.empty() && !pred(cur.get())) {
- this->inc();
- }
- }
-
- void forget() { cur.forget(); }
- bool empty() const { return cur.empty(); }
- void inc() {
- for (;;) {
- cur.inc();
- if (cur.empty() || pred(cur.get())) break;
- }
- }
- reference_type get() const {
- return cur.get();
- }
-
- bool atbegin() const { return atbegin(cur); }
- void dec() {
- for (;;) {
- cur.dec();
- if (pred(cur.get())) break;
- }
- }
- private:
- inner_cursor cur;
- Predicate pred;
- };
-
- linq_where(const Collection& c, Predicate pred) : c(c), pred(pred) {}
-
- cursor get_cursor() const {
- return cursor(c.get_cursor(), pred);
- }
-
- private:
- Collection c;
- Predicate pred;
- };
-}
-
-#endif // !defined(CPPLINQ_LINQ_WHERE_HPP)
-
diff --git a/Ix/CPP/src/cpplinq/util.hpp b/Ix/CPP/src/cpplinq/util.hpp
deleted file mode 100644
index ee3d7eb..0000000
--- a/Ix/CPP/src/cpplinq/util.hpp
+++ /dev/null
@@ -1,232 +0,0 @@
-// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
-
-#if !defined(CPPLINQ_LINQ_UTIL_HPP)
-#define CPPLINQ_LINQ_UTIL_HPP
-#pragma once
-
-namespace cpplinq { namespace util {
-
- template <class Container>
- struct container_traits {
- typedef typename Container::iterator iterator;
- typedef typename std::iterator_traits<iterator>::value_type value_type;
- typedef typename std::iterator_traits<iterator>::iterator_category iterator_category;
-
- // TODO: conservative definition for now.
- enum { is_writable_iterator =
- std::is_reference<typename std::iterator_traits<iterator>::reference>::value
- && std::is_same<typename std::remove_cv<value_type>::type,
- typename std::remove_cv<typename std::remove_reference<typename std::iterator_traits<iterator>::reference>::type>::type>::value
- };
- };
-
- template <>
- struct container_traits<int>;
-
- template <class Container>
- struct container_traits<Container&>
- : container_traits<Container>
- {};
- template <class Container>
- struct container_traits<const Container>
- : container_traits<Container>
- {
- typedef typename Container::const_iterator iterator;
- };
-
- // Note: returns false if no partial order exists between two
- // particular iterator categories, such as with some of the boost categories
- template <class Cat1, class Cat2>
- struct less_or_equal_iterator_category
- {
- private:
- typedef char yes;
- typedef struct { char c1,c2; } no;
- static yes invoke(Cat1);
- static no invoke(...);
- public:
- enum { value = (sizeof(invoke(Cat2())) == sizeof(yes)) };
- };
-
- // Return the weaker of the two iterator categories. Make sure
- // a non-standard category is in the second argument position, as
- // this metafunction will default to the first value if the order is undefined
- template <class Cat1, class Cat2>
- struct min_iterator_category
- : std::conditional<
- less_or_equal_iterator_category<Cat2, Cat1>::value,
- Cat2,
- Cat1>
- {
- };
-
-#if 0
-#define CppLinq_GET_ITERATOR_TYPE(TContainer) \
- decltype(begin(static_cast<TContainer*>(0)))
-#define CppLinq_GET_CONST_ITERATOR_TYPE(TContainer) \
- decltype(begin(static_cast<const TContainer*>(0)))
-#else
-#define CppLinq_GET_ITERATOR_TYPE(TContainer) \
- typename ::cpplinq::util::container_traits<TContainer>::iterator
-#define CppLinq_GET_CONST_ITERATOR_TYPE(TContainer) \
- typename ::cpplinq::util::container_traits<TContainer>::const_iterator
-#endif
-
- // VC10's std::tr1::result_of is busted with lambdas. use decltype instead on vc10 and later
-#if defined(_MSC_VER) && _MSC_VER >= 1600
- namespace detail {
- template <class T> T instance();
- };
- template <class Fn> struct result_of;
- template <class Fn>
- struct result_of<Fn()> {
- typedef decltype(detail::instance<Fn>()()) type;
- };
- template <class Fn, class A0>
- struct result_of<Fn(A0)> {
- typedef decltype(detail::instance<Fn>()(detail::instance<A0>())) type;
- };
- template <class Fn, class A0, class A1>
- struct result_of<Fn(A0,A1)> {
- typedef decltype(detail::instance<Fn>()(detail::instance<A0>(),
- detail::instance<A1>())) type;
- };
- template <class Fn, class A0, class A1, class A2>
- struct result_of<Fn(A0,A1,A2)> {
- typedef decltype(detail::instance<Fn>()(detail::instance<A0>(),
- detail::instance<A1>(),
- detail::instance<A2>())) type;
- };
- template <class Fn, class A0, class A1, class A2, class A3>
- struct result_of<Fn(A0,A1,A2,A3)> {
- typedef decltype(detail::instance<Fn>()(detail::instance<A0>(),
- detail::instance<A1>(),
- detail::instance<A2>(),
- detail::instance<A3>())) type;
- };
-#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& value) : value(value)
- {}
- value_ptr(const T* pvalue) : value(*pvalue)
- {}
- const T* operator->()
- {
- return &value;
- }
- };
-
-
- template <class T>
- class maybe
- {
- bool is_set;
- typename std::aligned_storage<sizeof(T), std::alignment_of<T>::value>::type
- storage;
- public:
- maybe()
- : is_set(false)
- {
- }
-
- maybe(T value)
- : is_set(false)
- {
- new (reinterpret_cast<T*>(&storage)) T(value);
- is_set = true;
- }
-
- maybe(const maybe& other)
- : is_set(false)
- {
- if (other.is_set) {
- new (reinterpret_cast<T*>(&storage)) T(*other.get());
- is_set = true;
- }
- }
- maybe(maybe&& other)
- : is_set(false)
- {
- if (other.is_set) {
- new (reinterpret_cast<T*>(&storage)) T(std::move(*other.get()));
- is_set = true;
- other.reset();
- }
- }
-
- ~maybe()
- {
- reset();
- }
-
- void reset()
- {
- if (is_set) {
- is_set = false;
- reinterpret_cast<T*>(&storage)->~T();
- }
- }
-
- T* get() {
- return is_set ? reinterpret_cast<T*>(&storage) : 0;
- }
-
- const T* get() const {
- return is_set ? reinterpret_cast<const T*>(&storage) : 0;
- }
-
- void set(T value) {
- if (is_set) {
- *reinterpret_cast<T*>(&storage) = std::move(value);
- } else {
- new (reinterpret_cast<T*>(&storage)) T(std::move(value));
- is_set = true;
- }
- }
-
- T& operator*() { return *get(); }
- const T& operator*() const { return *get(); }
- T* operator->() { return get(); }
- const T* operator->() const { return get(); }
-
- maybe& operator=(const T& other) {
- set(other);
- }
- maybe& operator=(const maybe& other) {
- if (const T* pother = other.get()) {
- set(*pother);
- } else {
- reset();
- }
- return *this;
- }
-
- // boolean-like operators
- operator T*() { return get(); }
- operator const T*() const { return get(); }
-
- private:
-
- };
-}}
-
-
-#endif //CPPLINQ_UTIL_HPP
-