Skip to content

Commit 5c23627

Browse files
committed
Add ListOf<T>, a templated List container
1 parent fc20cfc commit 5c23627

File tree

3 files changed

+285
-0
lines changed

3 files changed

+285
-0
lines changed

inst/include/Rcpp/Vector.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,4 +65,6 @@ namespace Rcpp{
6565
#include <Rcpp/vector/LazyVector.h>
6666
#include <Rcpp/vector/swap.h>
6767

68+
#include <Rcpp/vector/ListOf.h>
69+
6870
#endif
Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
// ListOfProxy.h: Rcpp R/C++ interface class library -- proxy for ListOf<T>
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_proxy_ListOfProxy_h_
21+
#define Rcpp_proxy_ListOfProxy_h_
22+
23+
#define THIS static_cast<List>(this->list)[this->index]
24+
#define LHS static_cast<List>(lhs.list)[lhs.index]
25+
#define RHS static_cast<List>(rhs.list)[rhs.index]
26+
27+
namespace Rcpp {
28+
29+
template <typename T>
30+
class ListOf;
31+
32+
template <typename T>
33+
class ListOfProxy {
34+
public:
35+
36+
ListOfProxy(ListOf<T>& list_, int index_): list(list_), index(index_) {
37+
RCPP_DEBUG("ListOfProxy(ListOf& list_, int index_): list(list_), index(index_)\n");
38+
}
39+
40+
~ListOfProxy() {
41+
RCPP_DEBUG("~ListOfProxy()\n");
42+
}
43+
44+
// assignment operators
45+
inline ListOfProxy& operator=(const ListOfProxy& rhs) {
46+
THIS = RHS;
47+
return *this;
48+
}
49+
50+
inline ListOfProxy& operator=(T rhs) {
51+
THIS = rhs;
52+
return *this;
53+
}
54+
55+
// addition operators
56+
inline ListOfProxy operator+(const ListOfProxy& rhs) {
57+
as<T>(THIS) = as<T>(THIS) + as<T>(RHS);
58+
return *this;
59+
}
60+
61+
template <typename U>
62+
inline ListOfProxy operator+(const U& rhs) {
63+
as<T>(THIS) = as<T>(THIS) + rhs;
64+
return *this;
65+
}
66+
67+
template <typename U>
68+
friend inline ListOfProxy operator+(const U& lhs, const ListOfProxy& rhs) {
69+
return const_cast<ListOfProxy<T>&>(rhs).operator+(lhs);
70+
}
71+
72+
inline ListOfProxy& operator+=(const ListOfProxy& rhs) {
73+
as<T>(THIS) += as<T>(RHS);
74+
return *this;
75+
}
76+
77+
template <typename U>
78+
inline ListOfProxy& operator+=(const U& rhs) {
79+
as<T>(THIS) += rhs;
80+
return *this;
81+
}
82+
83+
// subtraction operators
84+
inline ListOfProxy operator-(const ListOfProxy& rhs) {
85+
as<T>(THIS) = as<T>(THIS) - as<T>(RHS);
86+
return *this;
87+
}
88+
89+
template <typename U>
90+
inline ListOfProxy operator-(const U& rhs) {
91+
as<T>(THIS) = as<T>(THIS) - rhs;
92+
return *this;
93+
}
94+
95+
template <typename U>
96+
friend inline ListOfProxy operator-(const U& lhs, const ListOfProxy& rhs) {
97+
return const_cast<ListOfProxy<T>&>(rhs).operator-(lhs);
98+
}
99+
100+
inline ListOfProxy& operator-=(const ListOfProxy& rhs) {
101+
as<T>(THIS) -= as<T>(RHS);
102+
return *this;
103+
}
104+
105+
template <typename U>
106+
inline ListOfProxy& operator-=(const U& rhs) {
107+
as<T>(THIS) -= rhs;
108+
return *this;
109+
}
110+
111+
// multiplication operators
112+
inline ListOfProxy operator*(const ListOfProxy& rhs) {
113+
as<T>(THIS) = as<T>(THIS) * as<T>(RHS);
114+
return *this;
115+
}
116+
117+
template <typename U>
118+
inline ListOfProxy operator*(const U& rhs) {
119+
as<T>(THIS) = as<T>(THIS) * rhs;
120+
return *this;
121+
}
122+
123+
template <typename U>
124+
friend inline ListOfProxy operator*(const U& lhs, const ListOfProxy& rhs) {
125+
return const_cast<ListOfProxy<T>&>(rhs).operator*(lhs);
126+
}
127+
128+
inline ListOfProxy& operator*=(const ListOfProxy& rhs) {
129+
as<T>(THIS) *= as<T>(RHS);
130+
return *this;
131+
}
132+
133+
template <typename U>
134+
inline ListOfProxy& operator*=(const U& rhs) {
135+
as<T>(THIS) *= rhs;
136+
return *this;
137+
}
138+
139+
// division operators
140+
inline ListOfProxy operator/(const ListOfProxy& rhs) {
141+
as<T>(THIS) = as<T>(THIS) / as<T>(RHS);
142+
return *this;
143+
}
144+
145+
template <typename U>
146+
inline ListOfProxy operator/(const U& rhs) {
147+
as<T>(THIS) = as<T>(THIS) / rhs;
148+
return *this;
149+
}
150+
151+
template <typename U>
152+
friend inline ListOfProxy operator/(const U& lhs, const ListOfProxy& rhs) {
153+
return const_cast<ListOfProxy<T>&>(rhs).operator/(lhs);
154+
}
155+
156+
inline ListOfProxy& operator/=(const ListOfProxy& rhs) {
157+
as<T>(THIS) /= as<T>(RHS);
158+
return *this;
159+
}
160+
161+
template <typename U>
162+
inline ListOfProxy& operator/=(const U& rhs) {
163+
as<T>(THIS) /= rhs;
164+
return *this;
165+
}
166+
167+
// read
168+
inline operator T() const {
169+
RCPP_DEBUG("operator T() const\n");
170+
return as<T>(THIS);
171+
}
172+
173+
inline operator SEXP() const {
174+
return THIS;
175+
}
176+
177+
// TODO: reference operator
178+
179+
private:
180+
ListOf<T>& list;
181+
int index;
182+
}; // ListOfProxy
183+
184+
}
185+
186+
#undef THIS
187+
#undef LHS
188+
#undef RHS
189+
190+
#endif

inst/include/Rcpp/vector/ListOf.h

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
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+
template <typename T> class ListOf;
25+
}
26+
27+
#include <Rcpp/proxy/ListOfProxy.h>
28+
29+
namespace Rcpp {
30+
31+
// defines used to clean up some of the code repetition
32+
#define THIS static_cast<List>(list)[index]
33+
#define LHS static_cast<List>(lhs.list)[lhs.index]
34+
#define RHS static_cast<List>(rhs.list)[rhs.index]
35+
36+
template <typename T>
37+
class ListOf: public List {
38+
39+
public:
40+
41+
ListOf() {}
42+
43+
ListOf(SEXP data_): List(data_) {}
44+
45+
template <typename U>
46+
ListOf(const U& data_): List(data_) {}
47+
48+
operator SEXP() const {
49+
return wrap(static_cast<const List&>(*this));
50+
}
51+
52+
ListOfProxy<T> operator[](int i) {
53+
return ListOfProxy<T>(*this, i);
54+
}
55+
56+
const ListOfProxy<T> operator[](int i) const {
57+
return ListOfProxy<T>(const_cast< ListOf<T>& >(*this), i);
58+
}
59+
60+
ListOfProxy<T> operator[](std::string str) {
61+
std::vector<std::string> names = as< std::vector<std::string> >(this->attr("names"));
62+
for (int i=0; i < this->size(); ++i) {
63+
if (names[i] == str) {
64+
return ListOfProxy<T>(*this, i);
65+
}
66+
}
67+
std::stringstream ss;
68+
ss << "No name '" << str << "' in the names of the list supplied";
69+
stop(ss.str());
70+
return ListOfProxy<T>(*this, -1); // silence compiler
71+
}
72+
73+
const ListOfProxy<T> operator[](std::string str) const {
74+
std::vector<std::string> names = as< std::vector<std::string> >(this->attr("names"));
75+
for (int i=0; i < this->size(); ++i) {
76+
if (names[i] == str) {
77+
return ListOfProxy<T>(const_cast< ListOf<T>& >(*this), i);
78+
}
79+
}
80+
std::stringstream ss;
81+
ss << "No name '" << str << "' in the names of the list supplied";
82+
return ListOfProxy<T>(*this, -1); // silence compiler
83+
}
84+
85+
}; // ListOf<T>
86+
87+
} // Rcpp
88+
89+
#undef THIS
90+
#undef LHS
91+
#undef RHS
92+
93+
#endif

0 commit comments

Comments
 (0)