2323#include < map>
2424#include < memory> // std::map
2525#include < optional>
26+ #include < set>
2627#include < string>
2728#include < string_view>
2829#include < utility> // std::pair
@@ -136,6 +137,17 @@ class GridLayout {
136137 }
137138
138139public:
140+ // / factory method
141+ // /
142+ // / This is for the common case where we want a 1D layout with a hardcoded
143+ // / number of entries (and we know at compile-time that it can't fail)
144+ template <int N>
145+ static GridLayout create_1d () noexcept {
146+ static_assert (N >= 1 , " N must be positive" );
147+ int dim[3 ] = {N, 0 , 0 };
148+ return GridLayout::create_ (1 , dim, nullptr , nullptr ).first ;
149+ }
150+
139151 // / factory method
140152 static std::pair<GridLayout, Status> try_from_dim (int rank, const int * dim) {
141153 return GridLayout::create_ (rank, dim, nullptr , nullptr );
@@ -245,6 +257,19 @@ struct CorePack {
245257 // / maps field names to pointers
246258 MapType map;
247259
260+ // / prefer this method over directly modifying layout
261+ // /
262+ // / @note This obviously requires that this->layout and this->my_fields are
263+ // / not nullptr.
264+ void override_layout (const GridLayout& new_layout) noexcept {
265+ // overriding this->layout implicitly updates the members of `my_fields`,
266+ // `my_fields->grid_(dimension|start|end)`, because these members all point
267+ // to statically sized C array members of GridLayout
268+ *this ->layout = new_layout;
269+ // make sure grid_rank remains up to date
270+ this ->my_fields ->grid_rank = this ->layout ->rank ();
271+ }
272+
248273 // / factory method that consumes a @p premade_map
249274 // /
250275 // / @param premade_map A string to pointer mapping. The keys of this argument
@@ -285,13 +310,24 @@ class FieldContainer {
285310 ~FieldContainer () = default ;
286311
287312 // / A factory method to make a simple 1d container
313+ // /
314+ // / @param ctx_pack The Grackle Configuration used for initialization
315+ // / @param buf_size The positive number of elements in the container
316+ // / @param exclude_fields Names of fields that should be excluded
317+ // /
318+ // / @note This is provided as a convenience. Do we really need it?
288319 static std::pair<FieldContainer, Status> create_1d (
289- const GrackleCtxPack& ctx_pack, int buf_size, bool disable_metal = false );
320+ const GrackleCtxPack& ctx_pack, int buf_size,
321+ const std::set<std::string>& exclude_fields = {});
290322
291323 // / A factory method to make a container
324+ // /
325+ // / @param ctx_pack The Grackle Configuration used for initialization
326+ // / @param layout The Grid layout to use
327+ // / @param exclude_fields Names of fields that should be excluded
292328 static std::pair<FieldContainer, Status> create (
293329 const GrackleCtxPack& ctx_pack, const GridLayout& layout,
294- bool disable_metal = false );
330+ const std::set<std::string>& exclude_fields = {} );
295331
296332 // / Create a clone of FieldContainer
297333 FieldContainer clone () const ;
@@ -302,7 +338,8 @@ class FieldContainer {
302338 // /
303339 // / @warning
304340 // / Setting bypass_check to `true` is risky. It primarily exists for the
305- // / case where you call this method in a loop
341+ // / case where you call this method in a loop and we already know that 2
342+ // / containers are compatible
306343 Status copy_into (FieldContainer& dest, bool bypass_check = false ) const {
307344 if (!(bypass_check || this ->same_grid_props (dest))) {
308345 return error::Adhoc (" grid properties are incompatible" );
@@ -321,9 +358,20 @@ class FieldContainer {
321358 // / returns whether `this` and @p other contains the same set of fields
322359 bool same_fields (const FieldContainer& other) const ;
323360
361+ /* *@{*/
362+ // / get the pointer to the wrapped @ref grackle_field_data instance
363+ // /
364+ // / @note
365+ // / This primarily exists to support Grackle API function. Avoid mutating
366+ // / the returned pointer
324367 const grackle_field_data* get_ptr () const { return data_.my_fields .get (); }
368+
369+ // NOLINTNEXTLINE(readability-make-member-function-const)
325370 grackle_field_data* get_ptr () { return data_.my_fields .get (); }
371+ /* *@}*/
326372
373+ /* *@{*/
374+ // / finds the field data pointer for the field with the specified name
327375 std::optional<gr_float*> find (std::string_view key) {
328376 auto s = data_.map .find (key);
329377 return (s != data_.map .end ()) ? std::optional{s->second } : std::nullopt ;
@@ -333,18 +381,40 @@ class FieldContainer {
333381 auto s = data_.map .find (key);
334382 return (s != data_.map .end ()) ? std::optional{s->second } : std::nullopt ;
335383 }
384+ /* *@}*/
385+
386+ /* *@{*/
387+ // / finds the field data pointer or aborts the program
388+ gr_float* get_or_abort (std::string_view key) {
389+ std::optional<gr_float*> tmp = find (key);
390+ if (!tmp.has_value ()) {
391+ std::string key_copy{key}; // required b/c key isn't '\0' terminated
392+ GR_INTERNAL_ERROR (" \" %s\" field wasn't found" , key_copy.c_str ());
393+ }
394+ return *tmp;
395+ }
336396
337- int n_fields () const { return static_cast <int >(data_.map .size ()); }
397+ const gr_float* get_or_abort (std::string_view key) const {
398+ std::optional<const gr_float*> tmp = find (key);
399+ if (!tmp.has_value ()) {
400+ std::string key_copy{key}; // required b/c key isn't '\0' terminated
401+ GR_INTERNAL_ERROR (" \" %s\" field wasn't found" , key_copy.c_str ());
402+ }
403+ return *tmp;
404+ }
405+ /* *@}*/
338406
339- int rank () const { return data_.my_fields -> grid_rank ; }
407+ const GridLayout& grid_layout () const { return * data_.layout ; }
340408
341- // / the number of elements per field (unaffected by ghost zones)
342- int elements_per_field () const { return data_.layout ->n_elements (); }
409+ int n_fields () const { return static_cast <int >(data_.map .size ()); }
343410
344411 // we define both of the following methods to support the writing of
345412 // range-based for-loops to iterate over key-buffer pairs
346413 MapType::const_iterator begin () const { return data_.map .begin (); }
347414 MapType::const_iterator end () const { return data_.map .end (); }
415+
416+ // teach googletest how to print this type
417+ friend void PrintTo (const FieldContainer& fc, std::ostream* os);
348418};
349419} // namespace grtest
350420
0 commit comments