diff options
Diffstat (limited to 'Ix/CPP/src/cpplinq/linq_cursor.hpp')
-rw-r--r-- | Ix/CPP/src/cpplinq/linq_cursor.hpp | 342 |
1 files changed, 0 insertions, 342 deletions
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 |