File: tensorview_iterator.h

package info (click to toggle)
bagel 1.2.2-8
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 134,940 kB
  • sloc: cpp: 1,236,571; javascript: 15,383; python: 1,461; ansic: 674; makefile: 253; sh: 109
file content (133 lines) | stat: -rw-r--r-- 5,116 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
/*
 * tensorview_iterator.h
 *
 *  Created on: Dec 28, 2013
 *      Author: evaleev
 */

#ifndef BTAS_TENSORVIEW_ITERATOR_H_
#define BTAS_TENSORVIEW_ITERATOR_H_

#include <cstddef>

#include <btas/storage_traits.h>

namespace btas {

  /// Iterates over elements of \c Storage using ordinal values of indices in \c Range

  template <typename Range, typename Storage>
  class TensorViewIterator : public std::iterator<typename std::conditional<std::is_const<Storage>::value,
                                                                            std::forward_iterator_tag,
                                                                            std::output_iterator_tag>::type,
                                                  typename std::conditional<std::is_const<Storage>::value,
                                                  const typename storage_traits<Storage>::value_type,
                                                        typename storage_traits<Storage>::value_type>::type>
  {
      struct Enabler {};

    public:
      typedef Storage storage_type;
      typedef std::reference_wrapper<storage_type> storageref_type;
      typedef std::reference_wrapper<const storage_type> ncstorageref_type;
      typedef std::iterator<typename std::conditional<std::is_const<Storage>::value,
          std::forward_iterator_tag,
          std::output_iterator_tag>::type,
          typename std::conditional<std::is_const<Storage>::value,
          const typename storage_traits<Storage>::value_type,
          typename storage_traits<Storage>::value_type>::type> base_type;
      using typename base_type::value_type;
      using typename base_type::pointer;
      using typename base_type::reference;
      using typename base_type::difference_type;
      using typename base_type::iterator_category;

    private:
      typedef typename Range::ordinal_subiterator subiterator;
      typedef typename Range::ordinal_iterator iterator;
      typedef typename iterator::value_type ordinal_type;
      typedef typename Range::index_type index_type;

    public:
      /// Default constructor
      TensorViewIterator() {}
      /// Destructor
      ~TensorViewIterator() {}

      TensorViewIterator(const typename Range::iterator& index_iter,
                         Storage& storage) :
        iter_(subiterator(std::make_pair(*index_iter,index_iter.range()->ordinal(*index_iter)),index_iter.range())),
        storageref_(storage) {}

      TensorViewIterator(const typename Range::iterator& index_iter,
                         const storageref_type& storage) :
        iter_(subiterator(std::make_pair(*index_iter,index_iter.range()->ordinal(*index_iter)),index_iter.range())),
        storageref_(storage) {}

      template <typename S = Storage>
      TensorViewIterator(const typename Range::iterator& index_iter,
                         const ncstorageref_type& storage,
                         typename std::enable_if<std::is_const<S>::value>::type* = 0) :
        iter_(subiterator(std::make_pair(*index_iter,index_iter.range()->ordinal(*index_iter)),index_iter.range())),
        // standard const_cast cannot "map" const into nontrivial structures, have to reinterpret here
        storageref_(reinterpret_cast<const storageref_type&>(storage)) {}

      TensorViewIterator(const typename Range::iterator& index_iter,
                         const ordinal_type& ord,
                         Storage& storage) :
        iter_(subiterator(std::make_pair(*index_iter,ord),index_iter.range())),
        storageref_(storage) {}


      TensorViewIterator(const iterator& iter,
                         Storage& storage) :
        iter_(iter), storageref_(storage) {}

      TensorViewIterator(iterator&& iter,
                         Storage& storage) :
        iter_(iter), storageref_(storage) {}

      TensorViewIterator& operator++() {
        ++iter_;
        return *this;
      }

      const reference operator*() const {
        return *(cbegin(storageref_.get()) + *iter_);
      }

      //template <class = typename std::enable_if<not std::is_const<storage_type>::value,Enabler>::type>
      template <typename S = Storage>
      typename std::enable_if<not std::is_const<S>::value,reference>::type
      operator*() {
        return *(begin(storageref_.get()) + *iter_);
      }

      const index_type& index() const {
        return first(*iter_.base());
      }

      template <typename R, typename S>
      friend bool operator==(const TensorViewIterator<R,S>&, const TensorViewIterator<R,S>&);

    private:
      iterator iter_;
      storageref_type storageref_;
  };

  template <typename Range, typename Storage>
  inline bool operator==(const TensorViewIterator<Range,Storage>& i1,
                         const TensorViewIterator<Range,Storage>& i2) {
    return i1.iter_ == i2.iter_;
  }

  template <typename Range, typename Storage>
  inline bool operator!=(const TensorViewIterator<Range,Storage>& i1,
                         const TensorViewIterator<Range,Storage>& i2) {
    return not (i1 == i2);
  }

}


#endif /* BTAS_TENSORVIEW_ITERATOR_H_ */