/* enoki/array_call.h -- Enoki arrays of pointers, support for array (virtual) method calls Copyright (c) 2019 Wenzel Jakob All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. */ #pragma once #include NAMESPACE_BEGIN(enoki) template struct call_support { call_support(const Storage &) { } }; template struct StaticArrayImpl::use_pointer_impl>> : StaticArrayImpl { using UnderlyingType = std::uintptr_t; using Base = StaticArrayImpl; ENOKI_ARRAY_DEFAULTS(StaticArrayImpl) using Base::derived; using Value = std::conditional_t; using Scalar = std::conditional_t; StaticArrayImpl() = default; StaticArrayImpl(Value value) : Base(UnderlyingType(value)) { } StaticArrayImpl(std::nullptr_t) : Base(UnderlyingType(0)) { } template > = 0> StaticArrayImpl(const T &b) : Base(b) { } template StaticArrayImpl(const T &b, detail::reinterpret_flag) : Base(b, detail::reinterpret_flag()) { } template == array_depth_v && array_size_v == Base::Size1 && array_depth_v == array_depth_v && array_size_v == Base::Size2 && Base::Size2 != 0> = 0> StaticArrayImpl(const T1 &a1, const T2 &a2) : Base(a1, a2) { } ENOKI_INLINE decltype(auto) coeff(size_t i) const { using Coeff = decltype(Base::coeff(i)); if constexpr (std::is_same_v) return (const Value &) Base::coeff(i); else return Base::coeff(i); } ENOKI_INLINE decltype(auto) coeff(size_t i) { using Coeff = decltype(Base::coeff(i)); if constexpr (std::is_same_v) return (Value &) Base::coeff(i); else return Base::coeff(i); } template ENOKI_INLINE size_t compress_(T *&ptr, const Mask &mask) const { return Base::compress_((UnderlyingType *&) ptr, mask); } auto operator->() const { using BaseType = std::decay_t>>; return call_support(derived()); } template Derived_& operator=(T&& t) { ENOKI_MARK_USED(t); if constexpr (std::is_same_v) return (Derived_ &) Base::operator=(UnderlyingType(0)); else if constexpr (std::is_convertible_v) return (Derived_ &) Base::operator=(UnderlyingType(t)); else return (Derived_ &) Base::operator=(std::forward(t)); } }; NAMESPACE_BEGIN(detail) template typename T, typename... Args> struct is_callable : std::false_type {}; template