22 auto print_value_impl(std::ostream& os, T
const& val, std::nullptr_t) -> decltype(os << val) {
23 return os <<
" val=" << val;
104 if (new_array_index < 0 || new_array_index >=
m_array_dim) {
105 std::ostringstream oss;
106 oss << *
this <<
" next_array_element(" << shift <<
"): out of range";
107 throw std::runtime_error(oss.str());
143 [[nodiscard]]
explicit operator bool()
const {
159 template <
typename Tag,
typename Container>
161 static_assert(Container::template has_tag_v<Tag>);
196 template <
typename This>
198 if (this_ref.m_offset.has_always_been_null()) {
200 return this_ref.raw_ptr();
202 if (this_ref.m_offset) {
208 if (
auto*
const base_ptr = this_ref.container_data(); base_ptr) {
210 return base_ptr + this_ref.m_array_dim * this_ref.m_offset.current_row() +
211 this_ref.m_array_index;
214 return decltype(this_ref.raw_ptr()){
nullptr};
217 return decltype(this_ref.raw_ptr()){
nullptr};
226 std::ostringstream oss;
227 oss << *
this <<
" attempt to dereference [T& operator*]";
228 throw std::runtime_error(oss.str());
237 std::ostringstream oss;
238 oss << *
this <<
" attempt to dereference [T const& operator*]";
239 throw std::runtime_error(oss.str());
243 [[nodiscard]]
explicit operator T*() {
247 [[nodiscard]]
explicit operator T
const *()
const {
256 if (!maybe_info->container().empty()) {
257 os <<
"cont=" << maybe_info->container() <<
' ';
262 auto size = maybe_info->size();
267 os << maybe_info->field();
271 os <<
' ' << dh.
m_offset <<
'/' << size;
302 return !(lhs ==
rhs);
347 explicit operator bool()
const {
350 explicit operator void*() {
353 explicit operator void const *()
const {
357 return os <<
"data_handle<void>{raw=" << dh.
m_raw_ptr <<
'}';
372 template <
typename T>
373 struct std::hash<
neuron::container::data_handle<T>> {
375 static_assert(
sizeof(std::size_t) ==
sizeof(T
const*));
376 if (
s.m_offset ||
s.m_offset.was_once_valid()) {
382 reinterpret_cast<std::size_t
>(
s.m_container_or_raw_ptr);
384 return reinterpret_cast<std::size_t
>(
s.m_container_or_raw_ptr);
390 struct std::hash<
neuron::container::data_handle<void>> {
392 static_assert(
sizeof(std::size_t) ==
sizeof(
void*));
393 return reinterpret_cast<std::size_t
>(
s.m_raw_ptr);
int cxx_demangle(const char *symbol, char **funcname, size_t *funcname_sz)
static double valid(void *v)
void move(Item *q1, Item *q2, Item *q3)
std::ostream & print_value(std::ostream &os, T const &val)
std::ostream & print_value_impl(std::ostream &os, T const &,...)
data_handle< T > find_data_handle(T *ptr)
std::unique_ptr< storage_info > find_container_info(void const *)
Try and find a helpful name for a container.
constexpr do_not_search_t do_not_search
In mechanism libraries, cannot use auto const token = nrn_ensure_model_data_are_sorted(); because the...
Explicit specialisation data_handle<void>.
data_handle(void *raw_ptr)
data_handle(do_not_search_t, void *raw_ptr)
friend std::ostream & operator<<(std::ostream &os, data_handle< void > const &dh)
bool refers_to_a_modern_data_structure() const
friend bool operator==(data_handle< void > const &lhs, data_handle< void > const &rhs)
Stable handle to a generic value.
void * m_container_or_raw_ptr
non_owning_identifier_without_container identifier() const
Get the identifier used by this handle.
friend bool operator!=(data_handle const &lhs, data_handle const &rhs)
static auto get_ptr_helper(This &this_ref)
T const * raw_ptr() const
bool refers_to_a_modern_data_structure() const
Query whether this data handle is in "modern" mode.
data_handle(do_not_search_t, T *raw_ptr)
Create a data_handle<T> wrapping the raw T*.
T const * container_data() const
data_handle(non_owning_identifier_without_container offset, T *const *container, int array_dim, int array_index)
friend bool operator==(data_handle const &lhs, data_handle const &rhs)
bool refers_to(Container const &container) const
Query whether this generic handle points to a value from the Tag field of the given container.
data_handle(T *raw_ptr)
Construct a data_handle from a plain pointer.
friend std::ostream & operator<<(std::ostream &os, data_handle const &dh)
std::size_t current_row() const
Get the current logical row number.
non_owning_identifier_without_container m_offset
T const & operator*() const
data_handle next_array_element(int shift=1) const
Get a data handle to a different element of the same array variable.
Non-template stable handle to a generic value.
A non-owning permutation-stable identifier for an entry in a container.
bool was_once_valid() const
Did the identifier use to refer to a valid entry?
std::size_t current_row() const
What is the current row?
std::size_t operator()(neuron::container::data_handle< T > const &s) const noexcept
std::size_t operator()(neuron::container::data_handle< void > const &s) const noexcept