1717#define NANOVDB_GRID_HANDLE_H_HAS_BEEN_INCLUDED
1818
1919#include < fstream> // for std::ifstream
20- #include < type_traits> // for std::void_t
2120#include < iostream> // for std::cerr/cout
2221#include < vector>
2322#include < initializer_list>
@@ -32,27 +31,6 @@ namespace nanovdb {
3231
3332struct GridHandleMetaData {uint64_t offset, size; GridType gridType;};
3433
35- // / @brief Detects whether @c BufferTraits<BufferT> defines @c hasDeviceSingle,
36- // / i.e. whether the buffer manages a single device-resident allocation.
37- // / @details Defaults to false when the trait member is absent, so pre-existing
38- // / BufferTraits specializations (in or out of tree) that only define
39- // / hasDeviceDual keep compiling unchanged.
40- template <typename BufferT, typename = void >
41- struct BufferHasDeviceSingle { static constexpr bool value = false ; };
42- template <typename BufferT>
43- struct BufferHasDeviceSingle <BufferT, std::void_t <decltype (BufferTraits<BufferT>::hasDeviceSingle)>>
44- { static constexpr bool value = BufferTraits<BufferT>::hasDeviceSingle; };
45-
46- // / @brief Companion detection for BufferTraits<...>::hasHostSingle: a
47- // / single-space buffer whose storage is host-accessible (e.g. a
48- // / pinned-resource cuda::Buffer). GridHandle does not support these
49- // / yet and rejects them with a named error below.
50- template <typename BufferT, typename = void >
51- struct BufferHasHostSingle { static constexpr bool value = false ; };
52- template <typename BufferT>
53- struct BufferHasHostSingle <BufferT, std::void_t <decltype (BufferTraits<BufferT>::hasHostSingle)>>
54- { static constexpr bool value = BufferTraits<BufferT>::hasHostSingle; };
55-
5634// / @brief This class serves to manage a buffer containing one or more NanoVDB Grids.
5735// /
5836// / @note It is important to note that this class does NOT depend on OpenVDB.
@@ -71,6 +49,16 @@ class GridHandle
7149 template <typename T>
7250 static T* no_const (const T* ptr) { return const_cast <T*>(ptr); }
7351
52+ // / @brief Shared lookup behind grid() and deviceGrid(): the @a n'th grid
53+ // / within @a base, or nullptr when @a base is null, @a n is out of
54+ // / range, or the value type does not match the grid.
55+ template <typename ValueT>
56+ const NanoGrid<ValueT>* gridAt (const void * base, uint32_t n) const
57+ {
58+ if (base == nullptr || n >= mMetaData .size () || mMetaData [n].gridType != toGridType<ValueT>()) return nullptr ;
59+ return util::PtrAdd<NanoGrid<ValueT>>(base, mMetaData [n].offset );
60+ }
61+
7462 // / @brief Adopts a buffer whose metadata is already known, so a deep copy
7563 // / does not re-parse and a non-default-constructible buffer (e.g.
7664 // / over a ResourceRef) never needs default construction.
@@ -241,11 +229,7 @@ class GridHandle
241229 // / or if the template parameter does not match the specified grid.
242230 template <typename ValueT, typename U = BufferT>
243231 typename util::enable_if<BufferHasDeviceSingle<U>::value, const NanoGrid<ValueT>*>::type
244- deviceGrid (uint32_t n=0 ) const {
245- const void *data = mBuffer .data ();
246- if (data == nullptr || n >= mMetaData .size () || mMetaData [n].gridType != toGridType<ValueT>()) return nullptr ;
247- return util::PtrAdd<NanoGrid<ValueT>>(data, mMetaData [n].offset );
248- }
232+ deviceGrid (uint32_t n=0 ) const { return this ->template gridAt <ValueT>(mBuffer .data (), n); }
249233 template <typename ValueT, typename U = BufferT>
250234 typename util::enable_if<BufferHasDeviceSingle<U>::value, NanoGrid<ValueT>*>::type
251235 deviceGrid (uint32_t n=0 ){return const_cast <NanoGrid<ValueT>*>(static_cast <const GridHandle*>(this )->template deviceGrid <ValueT>(n));}
@@ -463,11 +447,8 @@ template <typename OtherBufferT>
463447inline GridHandle<OtherBufferT> GridHandle<BufferT>::copy(const OtherBufferT& other) const
464448{
465449 if constexpr (BufferHasDeviceSingle<BufferT>::value || BufferHasDeviceSingle<OtherBufferT>::value) {
466- static_assert (util::is_same<OtherBufferT, BufferT>::value && BufferHasDeviceSingle<BufferT>::value,
467- " GridHandle::copy to or from a single-space device buffer of a different buffer type "
468- " is not supported yet: copy device-to-device with the same buffer type instead" );
469450 (void )other;// the single-space copy allocates through the source's resource
470- return this ->template copy <OtherBufferT>();
451+ return this ->template copy <OtherBufferT>();// the no-arg overload holds the supported-combination guard
471452 } else {
472453 if (mBuffer .size () == 0 ) return GridHandle<OtherBufferT>();// return an empty handle
473454 auto buffer = OtherBufferT::create (mBuffer .size (), &other);
@@ -498,19 +479,15 @@ template<typename BufferT>
498479template <typename ValueT, typename U, typename util::disable_if<BufferHasDeviceSingle<U>::value, int >::type>
499480inline const NanoGrid<ValueT>* GridHandle<BufferT>::grid(uint32_t n) const
500481{
501- const void *data = mBuffer .data ();
502- if (data == nullptr || n >= mMetaData .size () || mMetaData [n].gridType != toGridType<ValueT>()) return nullptr ;
503- return util::PtrAdd<NanoGrid<ValueT>>(data, mMetaData [n].offset );
482+ return this ->template gridAt <ValueT>(mBuffer .data (), n);
504483}// const NanoGrid<ValueT>* GridHandle<BufferT>::grid(uint32_t n) const
505484
506485template <typename BufferT>
507486template <typename ValueT, typename U>
508487inline typename util::enable_if<BufferTraits<U>::hasDeviceDual, const NanoGrid<ValueT>*>::type
509488GridHandle<BufferT>::deviceGrid(uint32_t n) const
510489{
511- const void *data = mBuffer .deviceData ();
512- if (data == nullptr || n >= mMetaData .size () || mMetaData [n].gridType != toGridType<ValueT>()) return nullptr ;
513- return util::PtrAdd<NanoGrid<ValueT>>(data, mMetaData [n].offset );
490+ return this ->template gridAt <ValueT>(mBuffer .deviceData (), n);
514491}// GridHandle<BufferT>::deviceGrid(uint32_t n) cons
515492
516493template <typename BufferT>
0 commit comments