File dense_1d.h
File List > dense > dense_1d.h
Go to the documentation of this file
/*****************************************************************/
#pragma once
#include <muda/viewer/viewer_base.h>
namespace muda
{
/*****************************************************************************
*
* Dense1D (1D array)
* indexing (x)
*
* A C/C++ array like viewer.
*
*****************************************************************************/
template <bool IsConst, typename T>
class Dense1DT : public ViewerBase<IsConst>
{
using Base = ViewerBase<IsConst>;
template <typename U>
using auto_const_t = typename Base::template auto_const_t<U>;
MUDA_VIEWER_COMMON_NAME(Dense1DT);
public:
using ConstViewer = Dense1DT<true, T>;
using NonConstViewer = Dense1DT<false, T>;
using ThisViewer = Dense1DT<IsConst, T>;
protected:
auto_const_t<T>* m_data = nullptr;
int m_dim = 0;
public:
using value_type = T;
MUDA_GENERIC Dense1DT() MUDA_NOEXCEPT = default;
MUDA_GENERIC Dense1DT(auto_const_t<T>* p, int dim) MUDA_NOEXCEPT : m_data(p),
m_dim(dim)
{
}
MUDA_GENERIC Dense1DT(const Dense1DT& other) = default;
template <bool OtherIsConst>
MUDA_GENERIC Dense1DT(const Dense1DT<OtherIsConst, T>& other) MUDA_NOEXCEPT
MUDA_REQUIRES(!OtherIsConst)
: m_data(other.data())
, m_dim(other.dim())
{
static_assert(OtherIsConst, "Only non-const viewer can be convert to const viewer");
}
MUDA_GENERIC auto as_const() const MUDA_NOEXCEPT
{
return ConstViewer{*this};
}
MUDA_GENERIC auto_const_t<T>& operator()(int x) const MUDA_NOEXCEPT
{
check();
return m_data[map(x)];
}
MUDA_GENERIC auto_const_t<T>* data() const MUDA_NOEXCEPT { return m_data; }
MUDA_GENERIC int total_size() const MUDA_NOEXCEPT { return m_dim; }
MUDA_GENERIC int dim() const MUDA_NOEXCEPT { return m_dim; }
MUDA_GENERIC ThisViewer subview(int offset) const MUDA_NOEXCEPT
{
auto size = this->m_dim - offset;
if constexpr(DEBUG_VIEWER)
{
if(offset < 0)
MUDA_KERNEL_ERROR("Dense1D[%s:%s]: subview out of range, offset=%d size=%d m_dim=(%d). %s(%d)",
this->name(),
this->kernel_name(),
offset,
size,
this->m_dim,
this->kernel_file(),
this->kernel_line());
}
return ThisViewer{this->m_data + offset, size};
}
MUDA_GENERIC ThisViewer subview(int offset, int size) const MUDA_NOEXCEPT
{
if constexpr(DEBUG_VIEWER)
{
if(offset < 0 || offset + size > m_dim)
MUDA_KERNEL_ERROR("Dense1D[%s:%s]: subview out of range, offset=%d size=%d m_dim=(%d). %s(%d)",
this->name(),
this->kernel_name(),
offset,
size,
this->m_dim,
this->kernel_file(),
this->kernel_line());
}
return ThisViewer{this->m_data + offset, size};
}
protected:
MUDA_INLINE MUDA_GENERIC void check() const MUDA_NOEXCEPT
{
if constexpr(DEBUG_VIEWER)
if(m_data == nullptr)
MUDA_KERNEL_ERROR("Dense1D[%s:%s]: m_data is null. %s(%d)",
this->name(),
this->kernel_name(),
this->kernel_file(),
this->kernel_line());
}
MUDA_GENERIC int map(int x) const MUDA_NOEXCEPT
{
if constexpr(DEBUG_VIEWER)
if(!(x >= 0 && x < m_dim))
MUDA_KERNEL_ERROR("Dense1D[%s:%s]: out of range, index=(%d) m_dim=(%d). %s(%d)",
this->name(),
this->kernel_name(),
x,
m_dim,
this->kernel_file(),
this->kernel_line());
return x;
}
};
template <typename T>
using Dense1D = Dense1DT<false, T>;
template <typename T>
using CDense1D = Dense1DT<true, T>;
// viewer traits
template <typename T>
struct read_only_viewer<Dense1D<T>>
{
using type = CDense1D<T>;
};
template <typename T>
struct read_write_viewer<CDense1D<T>>
{
using type = Dense1D<T>;
};
// make functions
template <typename T>
MUDA_INLINE MUDA_GENERIC auto make_cdense_1d(const T* data, int dimx) MUDA_NOEXCEPT
{
return CDense1D<T>(data, dimx);
}
template <typename T, int N>
MUDA_INLINE MUDA_GENERIC auto make_cdense_1d(const T (&data)[N]) MUDA_NOEXCEPT
{
return CDense1D<T>(data, N);
}
template <typename T>
MUDA_INLINE MUDA_GENERIC auto make_dense_1d(T* data, int dimx) MUDA_NOEXCEPT
{
return Dense1D<T>(data, dimx);
}
template <typename T, int N>
MUDA_INLINE MUDA_GENERIC auto make_dense_1d(T (&data)[N]) MUDA_NOEXCEPT
{
return Dense1D<T>(data, N);
}
} // namespace muda