Skip to content

Commit

Permalink
Start writing RecordArray (C++ and Fillable, but not Numba). (#25)
Browse files Browse the repository at this point in the history
Includes zero-field `RecordArray` (with non-zero length) and `tojson`/`fromjson`, but not Numba.

* [WIP] Start writing RecordArray (full scope to be determined).

* Skeleton for RecordArray.

* Modifiers compile.

* Tests pass.

* String representation of RecordArray is done.

* fields, key, and aliases.

* tojson_part is more sane; fixed FIXME in NumpyArray and added RecordArray::tojson_part.

* Some more helper functions compile.

* RecordArray utility functions work.

* Stubs for Record (scalar of RecordArray).

* Can produce Records from RecordArray.

* Record::tojson_part.

* tolist(Record).

* RecordType stub compiles.

* util::quote as a TODO stub for proper string-escapes.

* Fixed Windows errors and warnings.

* Actually test before committing.

* RecordType::equals.

* Done with RecordType (if Python dict order is okay).

* Content returns the right type for scalar and non-scalar data.

* Defined slices for a string key and a list of string keys.

* Stubbed out slicing of fields.

* Stubbed all Content::getitem_field and getitem_fields.

* Ready to start implementing getitem_field(s).

* Record and RecordArray::getitem_* except for all getitem_nexts.

* Better constructor for RecordArray.

* Ready to implement *::getitem_next(field?) and Record*::getitem_next(*).

* Implemented and tested *::getitem_field?.

* *::getitem_next(field?) can be defined in general, in terms of *::getitem_field?.

* Record*::getitem_next(*) are done.

* Slicing within records (if part of a chain, not on a single Record object).

* [skip ci] Save work (because the setid is actually functional; tracing down another bug).

* RecordArray::setid is done

* Fixed some Identity bugs and introduced location at Python-level.

* Fixed 32-bit warnings and added Record*::withoutkeys.

* Stubs for filling records.

* Fillable::beginrec should know the set of keys, even though this will be hard to provide from JSON.

* Formal Slots object.

* A fillable record type is defined by its slotsid; field names only taken once.

* TupleFillable is a simpler version of RecordFillable.

* First working version of FillableArray with tuples (RecordArray).

* Don't let any fields get ahead of the tuple.

* All tuple methods implemented, though only the main path has been tested.

* Updated stubs for RecordFillable, but I forgot about the nested case.

* Sketch out whole fillable algorithm in Python before implementing in C++.

* Repertoire of (mock) Content types for testing the Fillable algorithm.

* Stubbed out Fillable implementations.

* Filling in Fillable implementations.

* Filling in Fillable implementations (part 2).

* Filling in Fillable implementations (part 3; nested tuples are working).

* Filling in Fillable implementations (part 4; missing fields are working).

* Filling in Fillable implementations (part 5; nullptr returns are still needed in lists).

* Filling in Fillable implementations (part 6; working on nested lists: there's an error).

* Temporarily start a clean slate to try out this new 'active' idea.

* Building up new structure: 'active' obliviates the need for a special nullptr interpretation.

* Back up to the previous level, but simpler now.

* Put all checks into the same order.

* Started on unions.

* Seems I have 5 cases left...

* Studies of fillable-2 have full coverage (except error conditions and some printing).

* Move fillable-2 into place as the only fillable study.

* [skip ci] Cleared out all implementations to start again (tests will fail).

* [skip ci] Don't pass down FillableArray* because we don't need it.

* [skip ci] Uniform Fillable constructors.

* [skip ci] Copied implementations into UnknownFillable and OptionFillable.

* [skip ci] Copied implementations into UnionFillable.

* [skip ci] Copied implementations into ListFillable.

* [skip ci] Copied implementations into TupleFillable.

* [skip ci] Copied implementations into primitive Fillables.

* All tests pass with the new Fillable implementations.

* Ready to fill in implementations for RecordFillable.

* Implemented RecordFillable but have not tested it yet.

* fromiter with tuples.

* fromiter with records.

* Done with this PR. The next PR will put RecordArrays in Numba.

* RecordArray with zero fields and non-zero length is now possible.

* RecordArray now supports tojson/fromjson.
  • Loading branch information
jpivarski authored Nov 27, 2019
1 parent 4ce3970 commit 293184c
Show file tree
Hide file tree
Showing 66 changed files with 5,262 additions and 402 deletions.
10 changes: 6 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,11 @@ Completed items are ☑check-marked. See [closed PRs](https://github.com/scikit-
* [X] Reproduce all of the above as Numba extensions (make `NumpyArray`, `ListArray`, and `ListOffsetArray` usable in Numba-compiled functions).
* [X] Error messages with location-of-failure information if the array has an `Identity` (except in Numba).
* [X] Fully implement `__getitem__` for int/slice/intarray/boolarray/tuple (placeholders for newaxis/ellipsis), with perfect agreement with [Numpy basic/advanced indexing](https://docs.scipy.org/doc/numpy/reference/arrays.indexing.html), to all levels of depth.
* [ ] Appendable arrays (a distinct phase from readable arrays, when the type is still in flux) to implement `awkward.fromiter` in C++.
* [X] Appendable arrays (a distinct phase from readable arrays, when the type is still in flux) to implement `awkward.fromiter` in C++.
* [X] Implemented all types but records; tested all primitives and lists.
* [X] Expose appendable arrays to Numba.
* [ ] Implement appendable records.
* [ ] Test all (requires array types for all).
* [X] Implement appendable records.
* [X] Test all (tested in mock [studies/fillable.py](tree/master/studies/fillable.py)).
* [X] JSON → Awkward via header-only [RapidJSON](https://rapidjson.org) and `awkward.fromiter`.
* [ ] Explicit broadcasting functions for jagged and non-jagged arrays and scalars.
* [ ] Structure-preserving ufunc-like operation on the C++ side that applies a lambda function to inner data. The Python `__array_ufunc__` implementation will _call_ this to preserve structure.
Expand All @@ -74,7 +74,8 @@ Completed items are ☑check-marked. See [closed PRs](https://github.com/scikit-
* [X] `ListArray`: the new `JaggedArray`, based on `starts` and `stops` (i.e. fully general).
* [X] `ListOffsetArray`: the `JaggedArray` case with no unreachable data between reachable data (gaps).
* [X] `RegularArray`: for building rectilinear, N-dimensional arrays of arbitrary contents, e.g. putting jagged dimensions inside fixed dimensions.
* [ ] `RecordArray`: the new `Table` _without_ lazy-slicing.
* [X] `RecordArray`: the new `Table` _without_ lazy-slicing.
* [ ] Implement it in Numba as well.
* [ ] `MaskedArray`, `BitMaskedArray`, `IndexedMaskedArray`: same as the old versions.
* [ ] `UnionArray`: same as the old version; `SparseUnionArray`: the additional case found in Apache Arrow.
* [ ] `IndexedArray`: same as the old version.
Expand All @@ -89,6 +90,7 @@ Completed items are ☑check-marked. See [closed PRs](https://github.com/scikit-
* [ ] `PyVirtualArray`: takes a Python lambda (which gets carried into `VirtualArray`).
* [ ] `PyObjectArray`: same as the old version.
* [X] Describe high-level types using [datashape](https://datashape.readthedocs.io/en/latest/) and possibly also an in-house schema. (Emit datashape _strings_ from C++.)
* [ ] Type compatibility: option to treat nonexistent record fields as nullable data.
* [ ] Describe mid-level "persistence types" with no lengths, somewhat minimal JSON, optional dtypes/compression.
* [ ] Describe low-level layouts independently of filled arrays (JSON or something)?
* [ ] Layer 1 interface `Array`:
Expand Down
2 changes: 1 addition & 1 deletion VERSION_INFO
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.1.24
0.1.25
34 changes: 0 additions & 34 deletions awkward1/_numba/array/numpyarray.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,40 +123,6 @@ def lower_len(context, builder, sig, args):
proxyin = numba.cgutils.create_struct_proxy(tpe)(context, builder, value=val)
return numba.targets.arrayobj.array_len(context, builder, numba.intp(tpe.arraytpe), (proxyin.array,))

# def lower_getitem_nothing(context, builder, tpe, val):
# import awkward1._numba.identity
#
# proxyin = numba.cgutils.create_struct_proxy(tpe)(context, builder, value=val)
#
# proxyslice = numba.cgutils.create_struct_proxy(numba.types.slice2_type)(context, builder)
# proxyslice.start = context.get_constant(numba.intp, 0)
# proxyslice.stop = context.get_constant(numba.intp, 0)
# proxyslice.step = context.get_constant(numba.intp, 1)
# emptyslice = proxyslice._getvalue()
# emptyarray = numba.targets.arrayobj.getitem_arraynd_intp(context, builder, tpe.arraytpe(tpe.arraytpe, numba.types.slice2_type), (proxyin.array, emptyslice))
#
# if tpe.arraytpe.ndim > 1:
# shapetpe = numba.types.Tuple((numba.intp,) * tpe.arraytpe.ndim)
# shapeval = numba.targets.arrayobj.make_array(tpe.arraytpe)(context, builder, proxyin.array).shape
#
# newshapetpe = numba.types.Tuple((numba.intp,) * (tpe.arraytpe.ndim - 1))
# newshapeval = context.make_tuple(builder, newshapetpe, tuple(builder.extract_value(shapeval, i) for i in range(tpe.arraytpe.ndim - 1)))
#
# arraytpe = numba.types.Array(tpe.arraytpe.dtype, tpe.arraytpe.ndim - 1, tpe.arraytpe.layout)
# arrayval = numba.targets.arrayobj.array_reshape(context, builder, arraytpe(tpe.arraytpe, newshapetpe), (proxyin.array, newshapeval))
#
# else:
# arraytpe = tpe.arraytpe
# arrayval = emptyarray
#
# outtpe = NumpyArrayType(arraytpe, tpe.idtpe)
# proxyout = numba.cgutils.create_struct_proxy(outtpe)(context, builder)
# proxyout.array = arrayval
# if tpe.idtpe != numba.none:
# proxyout.id = awkward1._numba.identity.lower_getitem_any(context, builder, tpe.idtpe, numba.types.slice2_type, proxyin.id, emptyslice)
#
# return proxyout._getvalue()

@numba.extending.lower_builtin(operator.getitem, NumpyArrayType, numba.types.Integer)
@numba.extending.lower_builtin(operator.getitem, NumpyArrayType, numba.types.SliceType)
@numba.extending.lower_builtin(operator.getitem, NumpyArrayType, numba.types.Array)
Expand Down
9 changes: 9 additions & 0 deletions awkward1/operations/convert.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ def tolist(array):
if array is None or isinstance(array, (bool, str, bytes, numbers.Number)):
return array

elif isinstance(array, awkward1.layout.Record) and array.istuple:
return tuple(tolist(x) for x in array.values())

elif isinstance(array, awkward1.layout.Record):
return {n: tolist(x) for n, x in array.items()}

elif isinstance(array, numpy.ndarray):
return array.tolist()

Expand All @@ -43,6 +49,9 @@ def tojson(array, *args, **kwargs):
if array is None or isinstance(array, (bool, str, bytes, numbers.Number)):
return json.dumps(array)

elif isinstance(array, awkward1.layout.Record):
return array.tojson(*args, **kwargs)

elif isinstance(array, numpy.ndarray):
return awkward1.layout.NumpyArray(array).tojson(*args, **kwargs)

Expand Down
3 changes: 3 additions & 0 deletions awkward1/operations/describe.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ def typeof(array):
elif isinstance(array, numpy.generic):
raise ValueError("cannot describe {0} as a PrimitiveType".format(type(array)))

elif isinstance(array, awkward1.layout.Record):
return array.type

elif isinstance(array, numpy.ndarray):
if len(array.shape) == 0:
return typeof(array.reshape((1,))[0])
Expand Down
9 changes: 7 additions & 2 deletions include/awkward/Content.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,14 @@
#include "awkward/Identity.h"
#include "awkward/Slice.h"
#include "awkward/io/json.h"
#include "awkward/type/ArrayType.h"
#include "awkward/type/Type.h"

namespace awkward {
class Content {
public:
virtual ~Content() { }

virtual bool isscalar() const;
virtual const std::string classname() const = 0;
virtual const std::shared_ptr<Identity> id() const = 0;
virtual void setid() = 0;
Expand All @@ -31,12 +32,14 @@ namespace awkward {
virtual const std::shared_ptr<Content> getitem_at_nowrap(int64_t at) const = 0;
virtual const std::shared_ptr<Content> getitem_range(int64_t start, int64_t stop) const = 0;
virtual const std::shared_ptr<Content> getitem_range_nowrap(int64_t start, int64_t stop) const = 0;
virtual const std::shared_ptr<Content> getitem_field(const std::string& key) const = 0;
virtual const std::shared_ptr<Content> getitem_fields(const std::vector<std::string>& keys) const = 0;
virtual const std::shared_ptr<Content> getitem(const Slice& where) const;
virtual const std::shared_ptr<Content> getitem_next(const std::shared_ptr<SliceItem> head, const Slice& tail, const Index64& advanced) const;
virtual const std::shared_ptr<Content> carry(const Index64& carry) const = 0;
virtual const std::pair<int64_t, int64_t> minmax_depth() const = 0;

const ArrayType type() const;
const std::shared_ptr<Type> type() const;
const std::string tostring() const;
const std::string tojson(bool pretty, int64_t maxdecimals) const;
void tojson(FILE* destination, bool pretty, int64_t maxdecimals, int64_t buffersize) const;
Expand All @@ -47,6 +50,8 @@ namespace awkward {
virtual const std::shared_ptr<Content> getitem_next(const SliceEllipsis& ellipsis, const Slice& tail, const Index64& advanced) const;
virtual const std::shared_ptr<Content> getitem_next(const SliceNewAxis& newaxis, const Slice& tail, const Index64& advanced) const;
virtual const std::shared_ptr<Content> getitem_next(const SliceArray64& array, const Slice& tail, const Index64& advanced) const = 0;
virtual const std::shared_ptr<Content> getitem_next(const SliceField& field, const Slice& tail, const Index64& advanced) const;
virtual const std::shared_ptr<Content> getitem_next(const SliceFields& fields, const Slice& tail, const Index64& advanced) const;

const std::shared_ptr<Content> getitem_next_array_wrap(const std::shared_ptr<Content> outcontent, const std::vector<int64_t>& shape) const;

Expand Down
8 changes: 6 additions & 2 deletions include/awkward/Identity.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,14 @@ namespace awkward {
const int64_t length() const { return length_; }

virtual const std::string classname() const = 0;
virtual const std::string location(int64_t where) const = 0;
virtual const std::string location_at(int64_t where) const = 0;
virtual const std::shared_ptr<Identity> to64() const = 0;
virtual const std::string tostring_part(const std::string indent, const std::string pre, const std::string post) const = 0;
virtual const std::shared_ptr<Identity> getitem_range_nowrap(int64_t start, int64_t stop) const = 0;
virtual const std::shared_ptr<Identity> shallow_copy() const = 0;
virtual const std::shared_ptr<Identity> getitem_carry_64(const Index64& carry) const = 0;
virtual const std::shared_ptr<Identity> withfieldloc(const FieldLoc& fieldloc) const = 0;
virtual int64_t value(int64_t row, int64_t col) const = 0;

const std::string tostring() const;

Expand All @@ -63,12 +65,14 @@ namespace awkward {
const std::shared_ptr<T> ptr() const { return ptr_; }

virtual const std::string classname() const;
virtual const std::string location(int64_t where) const;
virtual const std::string location_at(int64_t at) const;
virtual const std::shared_ptr<Identity> to64() const;
virtual const std::string tostring_part(const std::string indent, const std::string pre, const std::string post) const;
virtual const std::shared_ptr<Identity> getitem_range_nowrap(int64_t start, int64_t stop) const;
virtual const std::shared_ptr<Identity> shallow_copy() const;
virtual const std::shared_ptr<Identity> getitem_carry_64(const Index64& carry) const;
virtual const std::shared_ptr<Identity> withfieldloc(const FieldLoc& fieldloc) const;
virtual int64_t value(int64_t row, int64_t col) const;

const std::vector<T> getitem_at(int64_t at) const;
const std::vector<T> getitem_at_nowrap(int64_t at) const;
Expand Down
6 changes: 3 additions & 3 deletions include/awkward/Iterator.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ namespace awkward {
public:
Iterator(const std::shared_ptr<Content> content)
: content_(content)
, where_(0) {
, at_(0) {
content.get()->check_for_iteration();
}

const std::shared_ptr<Content> content() const { return content_; }
const int64_t where() const { return where_; }
const int64_t at() const { return at_; }

const bool isdone() const;
const std::shared_ptr<Content> next();
Expand All @@ -26,7 +26,7 @@ namespace awkward {

private:
const std::shared_ptr<Content> content_;
int64_t where_;
int64_t at_;
};
}

Expand Down
24 changes: 24 additions & 0 deletions include/awkward/Slice.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,30 @@ namespace awkward {

typedef SliceArrayOf<int64_t> SliceArray64;

class SliceField: public SliceItem {
public:
SliceField(const std::string& key): key_(key) { }
const std::string key() const { return key_; }
virtual const std::shared_ptr<SliceItem> shallow_copy() const {
return std::shared_ptr<SliceItem>(new SliceField(key_));
}
virtual const std::string tostring() const;
private:
const std::string key_;
};

class SliceFields: public SliceItem {
public:
SliceFields(const std::vector<std::string>& keys): keys_(keys) { }
const std::vector<std::string> keys() const { return keys_; }
virtual const std::shared_ptr<SliceItem> shallow_copy() const {
return std::shared_ptr<SliceItem>(new SliceFields(keys_));
}
virtual const std::string tostring() const;
private:
const std::vector<std::string> keys_;
};

class Slice {
public:
static int64_t none() { return SliceItem::none(); }
Expand Down
4 changes: 4 additions & 0 deletions include/awkward/array/EmptyArray.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,17 @@ namespace awkward {
virtual const std::shared_ptr<Content> getitem_at_nowrap(int64_t at) const;
virtual const std::shared_ptr<Content> getitem_range(int64_t start, int64_t stop) const;
virtual const std::shared_ptr<Content> getitem_range_nowrap(int64_t start, int64_t stop) const;
virtual const std::shared_ptr<Content> getitem_field(const std::string& key) const;
virtual const std::shared_ptr<Content> getitem_fields(const std::vector<std::string>& keys) const;
virtual const std::shared_ptr<Content> carry(const Index64& carry) const;
virtual const std::pair<int64_t, int64_t> minmax_depth() const;

protected:
virtual const std::shared_ptr<Content> getitem_next(const SliceAt& at, const Slice& tail, const Index64& advanced) const;
virtual const std::shared_ptr<Content> getitem_next(const SliceRange& range, const Slice& tail, const Index64& advanced) const;
virtual const std::shared_ptr<Content> getitem_next(const SliceArray64& array, const Slice& tail, const Index64& advanced) const;
virtual const std::shared_ptr<Content> getitem_next(const SliceField& field, const Slice& tail, const Index64& advanced) const;
virtual const std::shared_ptr<Content> getitem_next(const SliceFields& fields, const Slice& tail, const Index64& advanced) const;

private:
std::shared_ptr<Identity> id_;
Expand Down
2 changes: 2 additions & 0 deletions include/awkward/array/ListArray.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ namespace awkward {
virtual const std::shared_ptr<Content> getitem_at_nowrap(int64_t at) const;
virtual const std::shared_ptr<Content> getitem_range(int64_t start, int64_t stop) const;
virtual const std::shared_ptr<Content> getitem_range_nowrap(int64_t start, int64_t stop) const;
virtual const std::shared_ptr<Content> getitem_field(const std::string& key) const;
virtual const std::shared_ptr<Content> getitem_fields(const std::vector<std::string>& keys) const;
virtual const std::shared_ptr<Content> carry(const Index64& carry) const;
virtual const std::pair<int64_t, int64_t> minmax_depth() const;

Expand Down
2 changes: 2 additions & 0 deletions include/awkward/array/ListOffsetArray.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ namespace awkward {
virtual const std::shared_ptr<Content> getitem_at_nowrap(int64_t at) const;
virtual const std::shared_ptr<Content> getitem_range(int64_t start, int64_t stop) const;
virtual const std::shared_ptr<Content> getitem_range_nowrap(int64_t start, int64_t stop) const;
virtual const std::shared_ptr<Content> getitem_field(const std::string& key) const;
virtual const std::shared_ptr<Content> getitem_fields(const std::vector<std::string>& keys) const;
virtual const std::shared_ptr<Content> carry(const Index64& carry) const;
virtual const std::pair<int64_t, int64_t> minmax_depth() const;

Expand Down
16 changes: 15 additions & 1 deletion include/awkward/array/NumpyArray.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,13 @@ namespace awkward {
const std::string format() const { return format_; }

ssize_t ndim() const;
bool isscalar() const;
bool isempty() const;
void* byteptr() const;
void* byteptr(ssize_t at) const;
ssize_t bytelength() const;
uint8_t getbyte(ssize_t at) const;

virtual bool isscalar() const;
virtual const std::string classname() const;
virtual const std::shared_ptr<Identity> id() const { return id_; }
virtual void setid();
Expand All @@ -56,6 +56,8 @@ namespace awkward {
virtual const std::shared_ptr<Content> getitem_at_nowrap(int64_t at) const;
virtual const std::shared_ptr<Content> getitem_range(int64_t start, int64_t stop) const;
virtual const std::shared_ptr<Content> getitem_range_nowrap(int64_t start, int64_t stop) const;
virtual const std::shared_ptr<Content> getitem_field(const std::string& key) const;
virtual const std::shared_ptr<Content> getitem_fields(const std::vector<std::string>& keys) const;
virtual const std::shared_ptr<Content> getitem(const Slice& where) const;
virtual const std::shared_ptr<Content> getitem_next(const std::shared_ptr<SliceItem> head, const Slice& tail, const Index64& advanced) const;
virtual const std::shared_ptr<Content> carry(const Index64& carry) const;
Expand All @@ -75,6 +77,12 @@ namespace awkward {
virtual const std::shared_ptr<Content> getitem_next(const SliceArray64& array, const Slice& tail, const Index64& advanced) const {
throw std::runtime_error("NumpyArray has its own getitem_next system");
}
virtual const std::shared_ptr<Content> getitem_next(const SliceField& field, const Slice& tail, const Index64& advanced) const {
throw std::runtime_error("NumpyArray has its own getitem_next system");
}
virtual const std::shared_ptr<Content> getitem_next(const SliceFields& fields, const Slice& tail, const Index64& advanced) const {
throw std::runtime_error("NumpyArray has its own getitem_next system");
}

const NumpyArray contiguous_next(Index64 bytepos) const;
const NumpyArray getitem_bystrides(const std::shared_ptr<SliceItem>& head, const Slice& tail, int64_t length) const;
Expand All @@ -89,6 +97,12 @@ namespace awkward {
const NumpyArray getitem_next(const SliceNewAxis& newaxis, const Slice& tail, const Index64& carry, const Index64& advanced, int64_t length, int64_t stride, bool first) const;
const NumpyArray getitem_next(const SliceArray64& array, const Slice& tail, const Index64& carry, const Index64& advanced, int64_t length, int64_t stride, bool first) const;

void tojson_boolean(ToJson& builder) const;
template <typename T>
void tojson_integer(ToJson& builder) const;
template <typename T>
void tojson_real(ToJson& builder) const;

private:
std::shared_ptr<Identity> id_;
std::shared_ptr<void> ptr_;
Expand Down
16 changes: 16 additions & 0 deletions include/awkward/array/RawArray.h
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,14 @@ namespace awkward {
return std::shared_ptr<Content>(new RawArrayOf<T>(id, ptr_, offset_ + start, stop - start, itemsize_));
}

virtual const std::shared_ptr<Content> getitem_field(const std::string& key) const {
throw std::invalid_argument(std::string("cannot slice ") + classname() + std::string(" by field name"));
}

virtual const std::shared_ptr<Content> getitem_fields(const std::vector<std::string>& keys) const {
throw std::invalid_argument(std::string("cannot slice ") + classname() + std::string(" by field name"));
}

virtual const std::shared_ptr<Content> getitem(const Slice& where) const {
std::shared_ptr<SliceItem> nexthead = where.head();
Slice nexttail = where.tail();
Expand Down Expand Up @@ -349,6 +357,14 @@ namespace awkward {
return carry(flathead);
}

virtual const std::shared_ptr<Content> getitem_next(const SliceField& field, const Slice& tail, const Index64& advanced) const {
throw std::invalid_argument(field.tostring() + std::string(" is not a valid slice type for ") + classname());
}

virtual const std::shared_ptr<Content> getitem_next(const SliceFields& fields, const Slice& tail, const Index64& advanced) const {
throw std::invalid_argument(fields.tostring() + std::string(" is not a valid slice type for ") + classname());
}

private:
std::shared_ptr<Identity> id_;
const std::shared_ptr<T> ptr_;
Expand Down
Loading

0 comments on commit 293184c

Please sign in to comment.