Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #ifndef _LINQ_HPP
- #define _LINQ_HPP
- #include <exception>
- #include <algorithm>
- #include <iterator>
- #include <type_traits>
- namespace linq
- {
- class invalid_query: public std::exception
- {
- };
- // if T::value_type is not valid, this can be specialized to
- // select the value type
- template <typename Iterable>
- struct get_value_type
- {
- typedef typename Iterable::value_type type;
- };
- // Determine if an iterator supports random access
- template <typename Iterator>
- struct is_random_access
- {
- typename std::is_same<typename std::iterator_traits<Iterator>::iterator_category, std::random_access_iterator_tag> type;
- };
- // Get the type of T's iterator
- template <typename Container>
- struct iterator_type
- {
- typedef decltype(begin(Container())) type;
- };
- // simple example
- template <typename T>
- bool always_true(T const& t)
- {
- return true;
- }
- template <typename Container, typename Value>
- class query_impl
- {
- public:
- typedef typename query_impl<Container, Value> this_type;
- typedef typename Container container_type;
- typedef typename Value value_type;
- typedef unsigned long long size_type;
- typedef typename iterator_type<Container>::type iterator;
- typedef typename iterator_type<const Container>::type const_iterator;
- typedef is_random_access<iterator> is_random_access;
- query_impl(container_type& t):
- _target(t)
- {
- }
- const_iterator begin() const
- {
- return std::begin(_target);
- }
- iterator begin()
- {
- return std::begin(_target);
- }
- const_iterator cbegin() const
- {
- return std::begin(_target);
- }
- const_iterator end() const
- {
- return std::end(_target);
- }
- iterator end()
- {
- return std::end(_target);
- }
- const_iterator cend() const
- {
- return std::end(_target);
- }
- container_type& target()
- {
- return _target;
- }
- container_type const& target() const
- {
- return _target;
- }
- size_type count() const
- {
- return std::distance(std::begin(_target), std::end(_target));
- }
- template <typename Func>
- bool all(Func func) const
- {
- for (auto it = std::begin(_target); it != std::end(_target); it++)
- {
- if (!func(*it))
- return false;
- }
- return true;
- }
- value_type sum() const
- {
- value_type v = value_type();
- for (auto it = std::begin(_target); it != std::end(_target); it++)
- v += *it;
- return v;
- }
- value_type& first() const
- {
- if (std::begin(_target) == std::end(_target))
- throw invalid_query();
- return *std::begin(_target);
- }
- value_type& first(value_type& default_) const
- {
- if (std::begin(_target) == std::end(_target))
- return default_;
- return *std::begin(_target);
- }
- value_type& last() const
- {
- if (std::begin(_target) == std::end(_target))
- throw invalid_query();
- return *(--std::end(_target));
- }
- value_type& last(value_type& default_) const
- {
- if (std::begin(_target) == std::end(_target))
- return default_;
- return *(--std::end(_target));
- }
- template <typename Pred>
- this_type& where(Pred predicate)
- {
- for (auto it = std::begin(_target); it != std::end(_target);)
- {
- if (predicate(*it))
- {
- it++;
- continue;
- }
- it = _target.erase(it);
- if (it == std::end(_target))
- break;
- }
- return *this;
- }
- this_type& skip(size_type count)
- {
- if (count > INT_MAX)
- throw std::overflow_error("count > INT_MAX");
- _target.erase(std::begin(_target), std::next(std::begin(_target), (int)count));
- return *this;
- }
- template <typename Func>
- this_type& select(Func func)
- {
- std::for_each(std::begin(_target), std::end(_target), func);
- return *this;
- }
- protected:
- container_type& _target;
- };
- // A type of query that copies the contents of the provided SourceContainer into a new ResultContainer
- // which is used as the target for queries.
- template <typename SourceContainer, typename Value, typename ResultContainer = std::vector<Value>>
- class query_impl_copy: public query_impl<ResultContainer, Value>
- {
- public:
- typedef SourceContainer source_container_type;
- query_impl_copy(source_container_type& t):
- query_impl(_result),
- _result(t.begin(), t.end())
- {
- }
- private:
- container_type _result;
- };
- // creates new query object and determines value type using get_value_type<Container>
- template <typename Container>
- query_impl<Container, typename get_value_type<Container>::type> query(Container& t)
- {
- return query_impl<Container, get_value_type<Container>::type>(t);
- }
- // explicit value type specification
- template <typename Container, typename Value>
- query_impl<Container, Value> query(Container& t)
- {
- return query_impl<Container, Value>(t);
- }
- // Create new copy query, which copies the data of the provided container to serve as the target
- // for queries.
- template <typename SourceContainer>
- query_impl_copy<SourceContainer, typename get_value_type<SourceContainer>::type> querycopy(SourceContainer& t)
- {
- return query_impl_copy<SourceContainer, get_value_type<SourceContainer>::type>(t);
- }
- } // namespace linq
- #endif // _LINQ_HPP
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement