Skip to content

Commit 09be88a

Browse files
Refactoring finished, all regression tests pass.
1 parent 9574588 commit 09be88a

File tree

6 files changed

+73
-54
lines changed

6 files changed

+73
-54
lines changed

RESTProcessExample/RESTProcessExample.cc

+2-1
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,8 @@ int main()
6363
if (!t.empty())
6464
read(t,jin);
6565
cout << toREST(cmd) <<"=>";
66-
write(registry.process(cmd, jin)->asBuffer(),cout,json5_parser::remove_trailing_zeros);
66+
auto result=registry.process(cmd, jin);
67+
write(result->asBuffer(),cout,json5_parser::remove_trailing_zeros);
6768
cout << endl;
6869
}
6970
catch (const std::exception& ex)

RESTProcess_base.h

+3-16
Original file line numberDiff line numberDiff line change
@@ -412,13 +412,7 @@ namespace classdesc
412412
{
413413
auto i=map.find("");
414414
if (i!=map.end())
415-
{
416-
auto r=i->second->process("",arguments);
417-
// if (std::is_base_of<MultiArrayBase, decltype(a)>::value)
418-
// if (auto v=r->toValue())
419-
// return v;
420-
return r;
421-
}
415+
return i->second->process("",arguments);
422416
else
423417
return {};
424418
}
@@ -691,10 +685,9 @@ namespace classdesc
691685

692686
public:
693687
RESTProcessSequence(T& obj): obj(obj) {}
694-
std::shared_ptr<classdesc::RESTProcessBase> process(const string& remainder, const REST_PROCESS_BUFFER& arguments) override;
688+
RPPtr process(const string& remainder, const REST_PROCESS_BUFFER& arguments) override;
695689
std::vector<Signature> signature() const override;
696690
RESTProcess_t list() const override;
697-
//{return makeRESTProcessValueObject({".@elem",".@elemNoThrow",".@insert",".@erase",".@size"});}
698691
std::string type() const override {return typeName<T>();}
699692
REST_PROCESS_BUFFER asBuffer() const override {REST_PROCESS_BUFFER r; return r<<obj;}
700693
RPPtr toValue() const override;
@@ -732,19 +725,13 @@ namespace classdesc
732725
public:
733726
template <class... Args>
734727
RESTProcessMultiArray(Args&&... args): actual(std::forward<Args>(args)...) {}
735-
RPPtr process(const string& remainder, const REST_PROCESS_BUFFER& arguments) override {
736-
// TODO - reuse sequence code to extract the slice
737-
return std::make_shared<RESTProcessVoid>();
738-
}
728+
RPPtr process(const string& remainder, const REST_PROCESS_BUFFER& arguments) override;
739729
REST_PROCESS_BUFFER asBuffer() const override {
740730
REST_PROCESS_BUFFER r;
741731
return r<<actual;
742732
}
743-
/// return signature(s) of the operations
744733
std::vector<Signature> signature() const override {return {};}
745-
/// return list of subcommands to this
746734
RESTProcess_t list() const override {return {};}
747-
/// return type name of this
748735
std::string type() const override {return "typeName<T>()";}
749736
bool isObject() const override {return true;}
750737
RPPtr getElem(const REST_PROCESS_BUFFER& index) override {

RESTProcess_epilogue.h

+64-34
Original file line numberDiff line numberDiff line change
@@ -186,11 +186,12 @@ namespace classdesc
186186
}
187187
return bestOverload->process(remainder, arguments);
188188
}
189-
189+
190190
template <class T>
191-
RPPtr RESTProcessSequence<T>::process(const string& remainder, const REST_PROCESS_BUFFER& arguments)
191+
RPPtr sequenceProcess(T& obj, const string& remainder, const REST_PROCESS_BUFFER& arguments)
192192
{
193193
if (remainder.empty())
194+
{
194195
switch (arguments.type())
195196
{
196197
case RESTProcessType::null: break;
@@ -204,43 +205,72 @@ namespace classdesc
204205
convert(obj, arguments);
205206
break;
206207
}
207-
else if (startsWith(remainder,".@elem"))
208-
{
209-
// extract idx
210-
auto idxStart=find(remainder.begin()+1, remainder.end(), '.');
211-
if (idxStart==remainder.end())
212-
throw std::runtime_error("no index");
213-
auto idxEnd=find(idxStart+1, remainder.end(), '.');
214-
size_t idx=stoi(string(idxStart+1, idxEnd));
215-
if (idx>=obj.size())
216-
{
217-
if (startsWith(remainder,".@elemNoThrow"))
218-
return mapAndProcessDummy<typename T::value_type>(string(idxEnd,remainder.end()), arguments);
219-
else
220-
throw std::runtime_error("idx out of bounds");
221-
}
222-
return {};
223-
// auto i=obj.begin();
224-
// std::advance(i, idx);
225-
// auto ip=*i;
226-
// auto r=mapAndProcess(string(idxEnd,remainder.end()), arguments, ip);
227-
// // if we're processing MultiArrays, convert return to a value type as the iterator here will be invalidated out of scope
228-
// if (std::is_base_of<MultiArrayIterator, decltype(i)>::value)
229-
// if (auto v=r->toValue())
230-
// return v;
231-
// return r;
208+
return makeRESTProcessRef(obj);
232209
}
233-
else if (startsWith(remainder,".@insert"))
234-
insert(obj, arguments);
235-
else if (startsWith(remainder,".@erase"))
236-
erase(obj, arguments);
237210
else if (startsWith(remainder,".@size"))
238211
return makeRESTProcessValueObject(obj.size());
239-
else
240-
return RESTProcess_t(obj).process(remainder,arguments); // treat as an object, not container
241-
return std::make_shared<RESTProcessSequence>(obj);
212+
return RESTProcess_t(obj).process(remainder,arguments); // treat as an object, not container
242213
}
243214

215+
template <class T> std::tuple<typename T::iterator, string::size_type>
216+
elemImpl(T& obj, const string& remainder, const REST_PROCESS_BUFFER& arguments)
217+
{
218+
// extract idx
219+
assert(remainder.length()>2);
220+
auto idxStart=remainder.find('.',1);
221+
if (idxStart==string::npos)
222+
throw std::runtime_error("no index");
223+
auto idxEnd=remainder.find('.', idxStart+1);
224+
if (idxEnd==string::npos) idxEnd=remainder.length();
225+
size_t idx=stoi(remainder.substr(idxStart+1, idxEnd));
226+
if (idx>=obj.size())
227+
{
228+
// @elemNoThrow doesn't throw out of bounds error, but may throw invalid index
229+
if (startsWith(remainder,".@elemNoThrow"))
230+
return {obj.end(),string::npos};
231+
throw std::runtime_error("idx out of bounds");
232+
}
233+
auto i=obj.begin();
234+
std::advance(i, idx);
235+
return {i,idxEnd};
236+
}
237+
238+
template <class T> RPPtr RESTProcessSequence<T>::process(const string& remainder, const REST_PROCESS_BUFFER& arguments)
239+
{
240+
if (startsWith(remainder,".@elem"))
241+
{
242+
auto [i, idxEnd]=elemImpl(obj,remainder,arguments);
243+
if (i==obj.end()) return std::make_shared<RESTProcessVoid>();
244+
return mapAndProcess(remainder.substr(idxEnd), arguments, *i);
245+
}
246+
if (startsWith(remainder,".@insert"))
247+
{
248+
insert(obj, arguments);
249+
return makeRESTProcessRef(obj);
250+
}
251+
if (startsWith(remainder,".@erase"))
252+
{
253+
erase(obj, arguments);
254+
return makeRESTProcessRef(obj);
255+
}
256+
return sequenceProcess(obj,remainder,arguments);
257+
}
258+
259+
template <class T> RPPtr RESTProcessMultiArray<T>::process(const string& remainder, const REST_PROCESS_BUFFER& arguments)
260+
{
261+
if (startsWith(remainder,".@elem"))
262+
{
263+
auto [i, idxEnd]=elemImpl(actual,remainder,arguments);
264+
if (i==actual.end()) return std::make_shared<RESTProcessVoid>();
265+
auto r=mapAndProcess(remainder.substr(idxEnd), arguments, *i);
266+
if (idxEnd==remainder.length() && T::rank>1)
267+
// create a copy of the MultiArray iterator before it goes out of scope
268+
return std::make_shared<RESTProcessMultiArray<typename T::iterator::value_type>>(*i);
269+
return r;
270+
}
271+
return sequenceProcess(actual,remainder,arguments);
272+
}
273+
244274
template <class T>
245275
RPPtr RESTProcessAssociativeContainer<T>::process(const string& remainder, const REST_PROCESS_BUFFER& arguments)
246276
{

examples/old-polymorph.cc

-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88

99
#include "old-polymorph.h"
1010
#include "old-polymorph.cd"
11-
#include "object.cd"
1211
#include "pack_stream.h"
1312
#include "classdesc_epilogue.h"
1413

json_pack_base.h

+4-1
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,10 @@ namespace classdesc
306306
{
307307
using namespace json5_parser;
308308
if (d=="")
309-
o=json_pack_t(valueof(a));
309+
{
310+
json_pack_t tmp(valueof(a));
311+
o=tmp;
312+
}
310313
else
311314
{
312315
o.objectify();

test/testRef.cc

-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
//#include "ref.cd"
1111
#include "testRef.h"
1212
#include "testRef.cd"
13-
#include "object.cd"
1413
#include "classdesc_epilogue.h"
1514
using namespace classdesc;
1615

0 commit comments

Comments
 (0)