1 // ListOf.h: Rcpp R/C++ interface class library -- templated List container
2 //
3 // Copyright (C) 2014 Dirk Eddelbuettel, Romain Francois and Kevin Ushey
4 //
5 // This file is part of Rcpp.
6 //
7 // Rcpp is free software: you can redistribute it and/or modify it
8 // under the terms of the GNU General Public License as published by
9 // the Free Software Foundation, either version 2 of the License, or
10 // (at your option) any later version.
11 //
12 // Rcpp is distributed in the hope that it will be useful, but
13 // WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 // GNU General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with Rcpp.  If not, see <http://www.gnu.org/licenses/>.
19 
20 #ifndef Rcpp_vector_ListOf_h_
21 #define Rcpp_vector_ListOf_h_
22 
23 namespace Rcpp {
24 
25 template <typename T>
26 class ListOf
27     : public NamesProxyPolicy<T>
28     , public AttributeProxyPolicy<T>
29     , public RObjectMethods<T>
30 {
31 
32 public:
33     typedef typename traits::r_vector_iterator<VECSXP>::type iterator;
34     typedef typename traits::r_vector_const_iterator<VECSXP>::type const_iterator;
35 
ListOf()36     ListOf(): list(R_NilValue) {}
37 
ListOf(SEXP data_)38     ListOf(SEXP data_): list(data_) {
39         std::transform(list.begin(), list.end(), list.begin(), as<T>);
40     }
41 
42     template <typename U>
ListOf(const U & data_)43     ListOf(const U& data_): list(data_) {
44         std::transform(list.begin(), list.end(), list.begin(), as<T>);
45     }
46 
ListOf(const ListOf & other)47     ListOf(const ListOf& other): list(other.list) {}
48 
49     ListOf& operator=(const ListOf& other) {
50         if (this != &other) {
51             list = other.list;
52         }
53         return *this;
54     }
55 
56     template <typename U>
57     ListOf& operator=(const U& other) {
58         list = as<List>(other);
59         return *this;
60     }
61 
62     // subsetting operators
63 
64     ChildVector<T> operator[](R_xlen_t i) {
65         return ChildVector<T>(list[i], list, i);
66     }
67 
68     const ChildVector<T> operator[](R_xlen_t i) const {
69         return ChildVector<T>(list[i], list, i);
70     }
71 
72     ChildVector<T> operator[](const std::string& str) {
73         return ChildVector<T>(list[str], list, list.findName(str));
74     }
75 
76     const ChildVector<T> operator[](const std::string& str) const {
77         return ChildVector<T>(list[str], list, list.findName(str));
78     }
79 
80     // iteration operators pass down to list
81 
begin()82     inline iterator begin() {
83         return list.begin();
84     }
85 
end()86     inline iterator end() {
87         return list.end();
88     }
89 
begin()90     inline const_iterator begin() const {
91         return list.begin();
92     }
93 
end()94     inline const_iterator end() const {
95         return list.end();
96     }
97 
size()98     inline R_xlen_t size() const {
99         return list.size() ;
100     }
101 
get()102     inline List get() const {
103         return list;
104     }
105 
106     // conversion operators
SEXP()107     operator SEXP() const { return wrap(list); }
List()108     operator List() const { return list; }
109 
110 private:
111 
112     List list;
113 
114 }; // ListOf<T>
115 
116 // sapply, lapply wrappers
117 
118 namespace sugar {
119 
120 template <int RTYPE, bool NA, typename T, typename Function>
121 class Lapply;
122 
123 template <int RTYPE, bool NA, typename T, typename Function, bool NO_CONVERSION>
124 class Sapply;
125 
126 }
127 
128 template <typename T, typename Function>
lapply(const ListOf<T> & t,Function fun)129 List lapply(const ListOf<T>& t, Function fun) {
130     return lapply(t.get(), fun);
131 }
132 
133 template <typename T, typename Function>
sapply(const ListOf<T> & t,Function fun)134 T sapply(const ListOf<T>& t, Function fun) {
135     return sapply(t.get(), fun);
136 }
137 
138 } // Rcpp
139 
140 #endif
141