File: iterator.h

package info (click to toggle)
rcpp 1.1.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 7,480 kB
  • sloc: cpp: 27,436; ansic: 7,778; sh: 53; makefile: 2
file content (155 lines) | stat: -rw-r--r-- 4,955 bytes parent folder | download | duplicates (7)
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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8 -*-
//
// iterator.h: Rcpp R/C++ interface class library --
//
// Copyright (C) 2012 - 2013    Dirk Eddelbuettel and Romain Francois
//
// This file is part of Rcpp.
//
// Rcpp is free software: you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 2 of the License, or
// (at your option) any later version.
//
// Rcpp is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Rcpp.  If not, see <http://www.gnu.org/licenses/>.

#ifndef Rcpp__sugar__tools_iterator_h
#define Rcpp__sugar__tools_iterator_h

namespace Rcpp {
namespace sugar {

    /* generic sugar iterator type */
    template <typename T>
    class SugarIterator {
    public:

        typedef R_xlen_t difference_type ;
        typedef typename Rcpp::traits::storage_type< Rcpp::traits::r_sexptype_traits<T>::rtype >::type STORAGE_TYPE ;
        typedef STORAGE_TYPE reference ;
        typedef STORAGE_TYPE* pointer ;
        typedef std::random_access_iterator_tag iterator_category ;
        typedef SugarIterator iterator ;

        SugarIterator( const T& ref_ ) :ref(ref_), index(0) {}
        SugarIterator( const T& ref_, R_xlen_t index_) : ref(ref_), index(index_) {}
        SugarIterator( const SugarIterator& other) : ref(other.ref), index(other.index){}

        inline iterator& operator++(){ index++; return *this ; }
        inline iterator operator++(int){
            iterator orig(*this) ;
            ++(*this);
            return orig ;
        }
        inline iterator& operator--(){ index--; return *this ; }
        inline iterator operator--(int){
            iterator orig(*this) ;
            --(*this);
            return orig ;
        }
        inline iterator operator+(difference_type n) const {
			return iterator( ref, index+n ) ;
		}
		inline iterator operator-(difference_type n) const {
			return iterator( ref, index-n ) ;
		}
		inline iterator& operator+=(difference_type n) {
			index += n ;
			return *this ;
		}
		inline iterator& operator-=(difference_type n) {
			index -= n;
			return *this ;
		}
        inline reference operator[](R_xlen_t i){
		    return ref[index+i] ;
		}

		inline reference operator*() {
			return ref[index] ;
		}
		inline pointer operator->(){
			return &ref[index] ;
		}

		inline bool operator==( const iterator& y) const {
			return ( index == y.index ) ;
		}
		inline bool operator!=( const iterator& y) const {
			return ( index != y.index ) ;
		}
		inline bool operator<( const iterator& other ) const {
			return index < other.index ;
		}
		inline bool operator>( const iterator& other ) const {
			return index > other.index ;
		}
		inline bool operator<=( const iterator& other ) const {
			return index <= other.index ;
		}
		inline bool operator>=( const iterator& other ) const {
			return index >= other.index ;
		}

		inline difference_type operator-(const iterator& other) const {
			return index - other.index ;
		}


    private:
        const T& ref ;
        R_xlen_t index ;
    } ;

    template <typename T> struct sugar_const_iterator_type {
        typedef SugarIterator<T> type ;
    } ;
    template <int RTYPE> struct sugar_const_iterator_type< Rcpp::Vector<RTYPE> >{
        typedef typename Rcpp::Vector<RTYPE>::const_iterator type ;
    } ;
    template <> struct sugar_const_iterator_type< CharacterVector >{
        typedef SEXP* type ;
    } ;


    template <typename T> struct is_sugar_vector : public Rcpp::traits::false_type{} ;
    template <int RTYPE> struct is_sugar_vector< Rcpp::Vector<RTYPE> > : public Rcpp::traits::true_type{} ;


    template <typename T>
    inline typename sugar_const_iterator_type<T>::type get_const_begin__impl(const T& obj, Rcpp::traits::true_type ){
        return obj.begin() ;
    }
    template <typename T>
    inline typename sugar_const_iterator_type<T>::type get_const_begin__impl(const T& obj, Rcpp::traits::false_type ){
        typedef typename sugar_const_iterator_type<T>::type const_iterator ;
        return const_iterator( obj ) ;
    }



    template <typename T>
    inline typename sugar_const_iterator_type<T>::type get_const_begin(const T& obj){
        return get_const_begin__impl( obj, typename is_sugar_vector<T>::type() ) ;
    }
    /* full specialization for character vectors */
    template <>
    inline SEXP* get_const_begin(const CharacterVector& obj){
        return get_string_ptr(obj) ;
    }

    template <typename T>
    inline typename sugar_const_iterator_type<T>::type get_const_end(const T& obj){
        return get_const_begin<T>(obj) + obj.size() ;
    }


}
}
#endif