Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. //
  2. // Copyright 2013 Francisco Jerez
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a
  5. // copy of this software and associated documentation files (the "Software"),
  6. // to deal in the Software without restriction, including without limitation
  7. // the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8. // and/or sell copies of the Software, and to permit persons to whom the
  9. // Software is furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  17. // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
  18. // OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  19. // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  20. // OTHER DEALINGS IN THE SOFTWARE.
  21. //
  22.  
  23. #ifndef CLOVER_UTIL_ADAPTOR_HPP
  24. #define CLOVER_UTIL_ADAPTOR_HPP
  25.  
  26. #include <iterator>
  27.  
  28. #include "util/tuple.hpp"
  29. #include "util/pointer.hpp"
  30. #include "util/functional.hpp"
  31.  
  32. namespace clover {
  33.    namespace detail {
  34.       ///
  35.       /// Implementation of the iterator concept that transforms the
  36.       /// value of the source iterators \a Is on dereference by use of
  37.       /// a functor \a F.
  38.       ///
  39.       /// The exact category of the resulting iterator should be the
  40.       /// least common denominator of the source iterator categories.
  41.       ///
  42.       template<typename F, typename... Is>
  43.       class iterator_adaptor {
  44.       public:
  45.          typedef std::forward_iterator_tag iterator_category;
  46.          typedef typename std::result_of<
  47.                F(typename std::iterator_traits<Is>::reference...)
  48.             >::type reference;
  49.          typedef typename std::remove_reference<reference>::type value_type;
  50.          typedef pseudo_ptr<value_type> pointer;
  51.          typedef std::ptrdiff_t difference_type;
  52.  
  53.          iterator_adaptor() {
  54.          }
  55.  
  56.          iterator_adaptor(F f, std::tuple<Is...> &&its) :
  57.             f(f), its(std::move(its)) {
  58.          }
  59.  
  60.          reference
  61.          operator*() const {
  62.             return tuple::apply(f, tuple::map(derefs(), its));
  63.          }
  64.  
  65.          iterator_adaptor &
  66.          operator++() {
  67.             tuple::map(preincs(), its);
  68.             return *this;
  69.          }
  70.  
  71.          iterator_adaptor
  72.          operator++(int) {
  73.             auto jt = *this;
  74.             ++*this;
  75.             return jt;
  76.          }
  77.  
  78.          bool
  79.          operator==(const iterator_adaptor &jt) const {
  80.             return its == jt.its;
  81.          }
  82.  
  83.          bool
  84.          operator!=(const iterator_adaptor &jt) const {
  85.             return its != jt.its;
  86.          }
  87.  
  88.          pointer
  89.          operator->() const {
  90.             return { **this };
  91.          }
  92.  
  93.          iterator_adaptor &
  94.          operator--() {
  95.             tuple::map(predecs(), its);
  96.             return *this;
  97.          }
  98.  
  99.          iterator_adaptor
  100.          operator--(int) {
  101.             auto jt = *this;
  102.             --*this;
  103.             return jt;
  104.          }
  105.  
  106.          iterator_adaptor &
  107.          operator+=(difference_type n) {
  108.             tuple::map(advances_by(n), its);
  109.             return *this;
  110.          }
  111.  
  112.          iterator_adaptor &
  113.          operator-=(difference_type n) {
  114.             tuple::map(advances_by(-n), its);
  115.             return *this;
  116.          }
  117.  
  118.          iterator_adaptor
  119.          operator+(difference_type n) const {
  120.             auto jt = *this;
  121.             jt += n;
  122.             return jt;
  123.          }
  124.  
  125.          iterator_adaptor
  126.          operator-(difference_type n) const {
  127.             auto jt = *this;
  128.             jt -= n;
  129.             return jt;
  130.          }
  131.  
  132.          difference_type
  133.          operator-(const iterator_adaptor &jt) const {
  134.             return std::get<0>(its) - std::get<0>(jt.its);
  135.          }
  136.  
  137.          reference
  138.          operator[](difference_type n) const {
  139.             return *(*this + n);
  140.          }
  141.  
  142.          bool
  143.          operator<(iterator_adaptor &jt) const {
  144.             return *this - jt < 0;
  145.          }
  146.  
  147.          bool
  148.          operator>(iterator_adaptor &jt) const {
  149.             return *this - jt > 0;
  150.          }
  151.  
  152.          bool
  153.          operator>=(iterator_adaptor &jt) const {
  154.             return !(*this < jt);
  155.          }
  156.  
  157.          bool
  158.          operator<=(iterator_adaptor &jt) const {
  159.             return !(*this > jt);
  160.          }
  161.  
  162.       protected:
  163.          F f;
  164.          std::tuple<Is...> its;
  165.       };
  166.  
  167.       template<typename F, typename... Is>
  168.       iterator_adaptor<F, Is...>
  169.       operator+(typename iterator_adaptor<F, Is...>::difference_type n,
  170.                 const iterator_adaptor<F, Is...> &jt) {
  171.          return (jt + n);
  172.       }
  173.  
  174.       template<typename F, typename... Is>
  175.       iterator_adaptor<F, Is...>
  176.       operator-(typename iterator_adaptor<F, Is...>::difference_type n,
  177.                 const iterator_adaptor<F, Is...> &jt) {
  178.          return (jt - n);
  179.       }
  180.    }
  181. }
  182.  
  183. #endif
  184.