1#ifndef NGEN_BMI_UTILITIES_HPP
2#define NGEN_BMI_UTILITIES_HPP
11#include <boost/type_index.hpp>
12#include "bmi/Bmi_Adapter.hpp"
40 :
std::runtime_error(
"No C++ type corresponds to the BMI type name '" +
type_name +
"'")
88 if (type ==
"double" || type ==
"double precision")
89 return f.template operator()<
double>();
91 if (type ==
"long double")
92 return f.template operator()<
long double>();
94 if (type ==
"float" || type ==
"real")
95 return f.template operator()<
float>();
99 if (type ==
"int8" || type ==
"int8_t")
100 return f.template operator()<std::int8_t>();
102 if (type ==
"uint8" || type ==
"uint8_t")
103 return f.template operator()<std::uint8_t>();
105 if (type ==
"int16" || type ==
"int16_t")
106 return f.template operator()<std::int16_t>();
108 if (type ==
"uint16" || type ==
"uint16_t")
109 return f.template operator()<std::uint16_t>();
111 if (type ==
"int32" || type ==
"int32_t")
112 return f.template operator()<std::int32_t>();
114 if (type ==
"uint32" || type ==
"uint32_t")
115 return f.template operator()<std::uint32_t>();
117 if (type ==
"int64" || type ==
"int64_t")
118 return f.template operator()<std::int64_t>();
120 if (type ==
"uint64" || type ==
"uint64_t")
121 return f.template operator()<std::uint64_t>();
123 if (type ==
"short" || type ==
"short int" || type ==
"signed short" || type ==
"signed short int")
124 return f.template operator()<
short>();
126 if (type ==
"unsigned short" || type ==
"unsigned short int")
127 return f.template operator()<
unsigned short>();
129 if (type ==
"int" || type ==
"signed" || type ==
"signed int" || type ==
"integer")
130 return f.template operator()<
int>();
132 if (type ==
"unsigned" || type ==
"unsigned int")
133 return f.template operator()<
unsigned int>();
135 if (type ==
"long" || type ==
"long int" || type ==
"signed long" || type ==
"signed long int")
136 return f.template operator()<
long>();
138 if (type ==
"unsigned long" || type ==
"unsigned long int")
139 return f.template operator()<
unsigned long>();
141 if (type ==
"long long" || type ==
"long long int" || type ==
"signed long long" || type ==
"signed long long int")
142 return f.template operator()<
long long>();
144 if (type ==
"unsigned long long" || type ==
"unsigned long long int")
145 return f.template operator()<
unsigned long long>();
164 inline void require_item_size(
const std::string &type,
size_t item_size,
const std::string &described)
166 const size_t declared =
with_bmi_type(type, []<
typename T>() ->
size_t {
return sizeof(T); });
167 if (declared != item_size) {
168 throw std::runtime_error(
"Cannot use " + described +
": type '" + type +
"' is " +
169 std::to_string(declared) +
" bytes, but the model reports an item size of " +
170 std::to_string(item_size) +
" bytes.");
187 template<
typename TO,
typename FROM>
188 static inline std::vector<TO>
make_vector(
const FROM* data,
const size_t& count){
190 return std::vector<TO>(data, data+count);
208 template <
typename T,
typename Iterator>
213 std::shared_ptr<T> ptr(
new T[std::distance(begin, end)], [](T *p) {
delete[] p; } );
214 std::transform(begin, end, ptr.get(), [](
auto const& in){ return static_cast<T>(in); });
227 template <
typename Iterator>
230 return with_bmi_type(type, [&]<
typename T>() -> std::shared_ptr<void> {
246 return with_bmi_type(type, [&]<
typename U>() -> std::shared_ptr<void> {
247 return std::make_shared<U>(
static_cast<U
>(value));
269 template <
typename T>
272 const size_t item_size =
static_cast<size_t>(model.
GetVarItemsize(name));
273 if (item_size !=
sizeof(T)) {
274 throw std::runtime_error(
"Cannot get pointer to variable " + name +
" of model " +
276 " byte type; its items are " + std::to_string(item_size) +
" bytes.");
290 template <
typename T>
295 if( total_mem == 0 || item_size == 0){
305 throw std::runtime_error(
"Unable to get value of variable "+name+
". Model "+ model.
get_model_name() +
306 " reports no valid items (Nbytes = "+std::to_string(total_mem) +
307 ", Itemsize = "+std::to_string(item_size)+
".");
309 int num_items = total_mem/item_size;
314 void* data = ::operator
new(total_mem);
317 auto sptr = std::shared_ptr<void>(data, [](
void *p) { ::operator
delete(p); });
325 "variable '" + name +
"' of model '" + model.
get_model_name() +
"'");
326 return with_bmi_type(type, [&]<
typename S>() -> std::vector<T> {
331 throw std::runtime_error(
"Unable to get value of variable " + name +
332 " as " + boost::typeindex::type_id<T>().pretty_name() +
": no logic for converting variable type " + type);
virtual std::string GetVarType(std::string name)=0
virtual void * GetValuePtr(std::string name)=0
virtual void GetValue(std::string name, void *dest)=0
virtual int GetVarItemsize(std::string name)=0
virtual int GetVarNbytes(std::string name)=0
Abstract adapter interface for C++ classes to interact with the essential aspects of external models ...
Definition Bmi_Adapter.hpp:16
std::string get_model_name()
Get the model name.
Definition Bmi_Adapter.cpp:124
virtual const std::string get_analogous_cxx_type(const std::string &external_type_name, const size_t item_size)
Reduce a type name the backing model reports to one models::bmi::with_bmi_type resolves.
Definition Bmi_Adapter.hpp:81
static std::vector< TO > make_vector(const FROM *data, const size_t &count)
make a vector of type
Definition bmi_utilities.hpp:188
Definition deserialization.hpp:40
std::vector< T > GetValue(Bmi_Adapter &model, const std::string &name)
Copy values from a BMI model adapter and box them into a vector.
Definition bmi_utilities.hpp:291
void require_item_size(const std::string &type, size_t item_size, const std::string &described)
Throw unless type names a C++ type of exactly item_size bytes.
Definition bmi_utilities.hpp:164
T * GetValuePtr(Bmi_Adapter &model, const std::string &name)
Get a pointer to a model variable's own storage, addressed as.
Definition bmi_utilities.hpp:270
std::shared_ptr< void > get_value_as_type(std::string type, T value)
Gets a single value, casted based on type then returned as a typeless (void) pointer.
Definition bmi_utilities.hpp:244
std::shared_ptr< T > as_c_array(Iterator begin, Iterator end)
Template function for copying iterator range into contiguous array.
Definition bmi_utilities.hpp:209
std::shared_ptr< void > get_values_as_type(std::string type, Iterator begin, Iterator end)
Gets values in iterator range, casted based on type then returned as typeless (void) pointer.
Definition bmi_utilities.hpp:228
auto with_bmi_type(const std::string &type, F &&f)
Call f with the C++ type that a BMI type name denotes.
Definition bmi_utilities.hpp:86
Definition AbstractCLibBmiAdapter.hpp:6
Thrown when a BMI type name has no C++ type behind it.
Definition bmi_utilities.hpp:38
std::string type_name
Definition bmi_utilities.hpp:43
unknown_bmi_type(const std::string &type_name)
Definition bmi_utilities.hpp:39