Skip to content

Commit 2e52627

Browse files
committed
Modify ListOf<T> as per @romainfrancois's suggestions
1 parent eb64c61 commit 2e52627

File tree

4 files changed

+121
-258
lines changed

4 files changed

+121
-258
lines changed

inst/include/Rcpp/proxy/ListOfProxy.h

Lines changed: 0 additions & 190 deletions
This file was deleted.

inst/include/Rcpp/vector/ListOf.h

Lines changed: 110 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -21,73 +21,137 @@
2121
#define Rcpp_vector_ListOf_h_
2222

2323
namespace Rcpp {
24-
template <typename T> class ListOf;
25-
}
26-
27-
#include <Rcpp/proxy/ListOfProxy.h>
2824

29-
namespace Rcpp {
25+
template <typename T>
26+
class ListOf {
3027

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]
28+
public:
29+
static const int RTYPE = traits::r_sexptype_traits<T>::rtype;
30+
typedef typename traits::r_vector_iterator<RTYPE>::type iterator ;
31+
typedef typename traits::r_vector_const_iterator<RTYPE>::type const_iterator ;
3532

36-
template <typename T>
37-
class ListOf: public List {
33+
ListOf(): list(R_NilValue) {};
3834

39-
public:
35+
ListOf(SEXP data_): list(data_) {};
4036

41-
ListOf() {}
37+
template <typename U>
38+
ListOf(const U& data_): list(data_) {};
4239

43-
ListOf(SEXP data_): List(data_) {}
40+
ListOf(const ListOf& other): list(other.list) {};
41+
ListOf& operator=(const ListOf& other) {
42+
if (this != &other) {
43+
list = other.list;
44+
}
45+
return *this;
46+
}
4447

4548
template <typename U>
46-
ListOf(const U& data_): List(data_) {}
49+
ListOf& operator=(const U& other) {
50+
list = as<List>(other);
51+
return *this;
52+
}
53+
54+
// subsetting operators
4755

48-
operator SEXP() const {
49-
return wrap(static_cast<const List&>(*this));
56+
T operator[](int i) {
57+
return list[i];
5058
}
5159

52-
ListOfProxy<T> operator[](int i) {
53-
return ListOfProxy<T>(*this, i);
60+
const T operator[](int i) const {
61+
return list[i];
5462
}
5563

56-
const ListOfProxy<T> operator[](int i) const {
57-
return ListOfProxy<T>(const_cast< ListOf<T>& >(*this), i);
64+
T operator[](const std::string& str) {
65+
return list[str];
5866
}
5967

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
68+
const T operator[](const std::string& str) const {
69+
return list[str];
70+
}
71+
72+
// iteration operators pass down to list
73+
74+
inline iterator begin() {
75+
return list.begin();
76+
}
77+
78+
inline iterator end() {
79+
return list.end();
80+
}
81+
82+
inline const_iterator begin() const {
83+
return list.begin();
84+
}
85+
86+
inline const_iterator end() const {
87+
return list.end();
7188
}
7289

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);
90+
class ListOfProxy {
91+
92+
public:
93+
ListOfProxy(List& list_): list(list_) {};
94+
95+
List::Proxy operator[](int i) {
96+
return List::Proxy(list, i);
7897
}
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
98+
99+
List::Proxy operator[](const char* str) {
100+
std::vector<std::string> names = as< std::vector<std::string> >(list.attr("names"));
101+
for (int i=0; i < list.size(); ++i) {
102+
if (names[i] == str) {
103+
return List::Proxy(list, i);
104+
}
105+
}
106+
std::stringstream ss;
107+
ss << "No name '" << str << "' in the names of the list supplied";
108+
stop(ss.str());
109+
return List::Proxy(list, -1);
110+
}
111+
112+
private:
113+
ListOfProxy() {};
114+
115+
List& list;
116+
};
117+
118+
friend class ListOfProxy;
119+
120+
// lhs access
121+
friend ListOfProxy lhs(ListOf& x) {
122+
return ListOfProxy(x.list);
83123
}
84124

85-
}; // ListOf<T>
125+
// conversion operators
126+
operator SEXP() const { return wrap(list); }
127+
operator List() const { return list; }
86128

87-
} // Rcpp
129+
List list;
130+
131+
}; // ListOf<T>
132+
133+
// sapply, lapply wrappers
134+
135+
namespace sugar {
88136

89-
#undef THIS
90-
#undef LHS
91-
#undef RHS
137+
template <int RTYPE, bool NA, typename T, typename Function>
138+
class Lapply;
139+
140+
template <int RTYPE, bool NA, typename T, typename Function, bool NO_CONVERSION>
141+
class Sapply;
142+
143+
}
144+
145+
template <typename T, typename Function>
146+
List lapply(const ListOf<T>& t, Function fun) {
147+
return lapply(t.list, fun);
148+
}
149+
150+
template <typename T, typename Function>
151+
T sapply(const ListOf<T>& t, Function fun) {
152+
return sapply(t.list, fun);
153+
}
154+
155+
} // Rcpp
92156

93157
#endif

0 commit comments

Comments
 (0)