summaryrefslogtreecommitdiff
path: root/Ix/CPP/src/cpplinq/linq_cursor.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'Ix/CPP/src/cpplinq/linq_cursor.hpp')
-rw-r--r--Ix/CPP/src/cpplinq/linq_cursor.hpp342
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