Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /***********************************************************************
- /
- / Defines functions that provide access to fields of the chemistry_data
- / struct by dynamically specifying strings. If external applications use
- / these functions to access/set fields, rather than directly accessing
- / the fields of the struct, the applications will be to maintain
- / compatability with multiple versions grackle (as more fields get added
- / to chemistry_data)
- /
- /
- / Copyright (c) 2013, Enzo/Grackle Development Team.
- /
- / Distributed under the terms of the Enzo Public Licence.
- /
- / The full license is in the file LICENSE, distributed with this
- / software.
- ************************************************************************/
- #include <stddef.h>
- #include <string.h>
- #include "grackle_chemistry_data.h"
- // initialize _param_list_int and _param_list_double, which respectively hold
- // an entry for each int and double field in chemistry_data. These are only
- // used internally
- typedef struct { const size_t offset; const char * name; } param_entry;
- #define _LIST_INT_INT(FIELD) {offsetof(chemistry_data, FIELD), #FIELD},
- #define _LIST_INT_DOUBLE(FIELD) /* ... */
- #define _LIST_INT_STRING(FIELD) /* ... */
- #define _LIST_DOUBLE_INT(FIELD) /* ... */
- #define _LIST_DOUBLE_DOUBLE(FIELD) {offsetof(chemistry_data, FIELD), #FIELD},
- #define _LIST_DOUBLE_STRING(FIELD) /* ... */
- static const param_entry _int_param_list[] = {
- #define ENTRY(FIELD, TYPE, DEFAULT_VAL) _LIST_ELEM_INT_ ## TYPE(FIELD)
- #include "grackle_chemistry_data_fields.def"
- #undef ENTRY
- };
- static const param_entry _double_param_list[] = {
- #define ENTRY(FIELD, TYPE, DEFAULT_VAL) _LIST_ELEM_DOUBLE_ ## TYPE(FIELD)
- #include "grackle_chemistry_data_fields.def"
- #undef ENTRY
- };
- // initialize _n_int_params and _n_double_params, which respectively store the
- // lengths of _int_param_list & _double_param_list
- static const size_t _n_int_params =
- sizeof(_int_param_list) / sizeof(param_entry);
- static const size_t _n_double_params =
- sizeof(_double_param_list) / sizeof(param_entry);
- // define functions for accessing field values
- // - local_chemistry_data_access_double
- // - local_chemistry_data_access_int
- //
- // The current implementation has O(N) complexity where N is the number of
- // fields of chemistry_data. Since configuration just happens once, this
- // probably doesn't need to be very fast...
- //
- // A faster implementation that does a lot less work at runtime is definitely
- // possible (it would just involve more code).
- // retrieves a pointer to the field of my_chemistry that's named ``name``.
- //
- // This returns a NULL pointer if: my_chemistry is NULL, the field doesn't
- // exist, or the field doesn't have the specified type
- static void* _get_field_ptr(chemistry_data* my_chemistry, const char* name,
- int is_int)
- {
- if (my_chemistry == NULL) { return NULL; }
- const param_entry* l = (is_int == 1) ? _int_param_list : _double_param_list;
- const size_t length = (is_int == 1) ? _n_int_params : _n_double_params;
- for (size_t param_index = 0; param_index < length; param_index++){
- const param_entry* entry = l + param_index;
- if (strcmp(entry->name, name) == 0){
- return (void*)( (char*)my_chemistry + entry->offset );
- }
- }
- return NULL;
- }
- double* local_chemistry_data_access_double(chemistry_data* my_chemistry,
- const char* param_name)
- { return (double*)_get_field_ptr(my_chemistry, param_name, 0); }
- int* local_chemistry_data_access_int(chemistry_data* my_chemistry,
- const char* param_name)
- { return (int*)_get_field_ptr(my_chemistry, param_name, 1); }
- // define functions for accessing the names of chemistry_data
- // - param_name_double
- // - param_name_int
- //
- // These are primarily needed for testing purposes and can be used for
- // serialization. The current implementation is slow. A faster alternative
- // would define separate lists for int parameters and double parameters
- // returns the name of the ``i``th parameter of the specified type. This returns
- // NULL when there are ``i`` or fewer parameters of the specified type
- static const char* _param_name(size_t i, int is_int)
- {
- const param_entry* l = (is_int == 1) ? _int_param_list : _double_param_list;
- size_t length = (is_int == 1) ? _n_int_params : _n_double_params;
- return (i < length) ? l[i].name : NULL;
- }
- const char* param_name_double(size_t i){ return _param_name(i, 0); }
- const char* param_name_int(size_t i){ return _param_name(i, 1); }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement