1#ifndef _BBM_NATIVE_ARRAY_H_
2#define _BBM_NATIVE_ARRAY_H_
21 template<
typename T,
size_t N>
struct array;
26 template<
typename T,
size_t N>
27 struct array_impl :
public std::array<T,N>
29 using base_type = std::array<T,N>;
33 using base_type::operator[];
34 using base_type::begin;
35 using base_type::rbegin;
37 using base_type::rend;
39 using base_type::empty;
40 using base_type::size;
41 using typename base_type::value_type;
45 template<
typename U>
requires std::convertible_to<U,T>
46 array_impl(
const array_impl<U,N>& src) : base_type() { std::copy(src.begin(), src.end(), begin()); }
49 array_impl(
const T& t=0) : base_type() { std::fill(begin(), end(), t); }
52 template<
typename... U>
requires (
sizeof...(U) > 1)
53 array_impl(U&&... u) : base_type{T(u)...} {}
56 array_impl(std::array<T,N>&& src) : base_type(
std::forward<decltype(src)>(src)) {}
59 template<
typename U>
requires requires(T a, U
b) {{a=
b};}
60 array_impl& operator=(
const array_impl<U,N>& src)
62 std::copy(src.begin(), src.end(),
begin());
67 template<
typename U>
requires requires(T a, U
b) {{a=
b};}
68 array_impl& operator=(U&& src)
75 inline auto operator-(
void)
const {
return apply_op( std::negate<>() ); }
76 inline auto&
operator++(
void) {
return apply_op_inplace( [](
auto& r) {
return ++
r; }); }
77 inline auto&
operator--(
void) {
return apply_op_inplace( [](
auto& r) {
return --
r; }); }
78 inline auto operator++(
int) {
auto ret = *
this; ++(*this);
return ret; }
79 inline auto operator--(
int) {
auto ret = *
this; ++(*this);
return ret; }
81 template<
typename U>
inline constexpr auto operator+(U&& u)
const {
return apply_op( std::plus<>(), u); }
82 template<
typename U>
inline constexpr auto operator-(U&& u)
const {
return apply_op( std::minus<>(), u); }
83 template<
typename U>
inline constexpr auto operator*(U&& u)
const {
return apply_op( std::multiplies<>(), u); }
84 template<
typename U>
inline constexpr auto operator/(U&& u)
const {
return apply_op( std::divides<>(), u); }
85 template<
typename U>
inline constexpr auto operator%(U&& u)
const {
return apply_op( std::modulus<>(), u); }
87 template<
typename U>
inline constexpr auto&
operator+=(U&& u) {
return apply_op_inplace( [](
auto& r,
auto& v) {
r +=
v; },
u); }
88 template<
typename U>
inline constexpr auto&
operator-=(U&& u) {
return apply_op_inplace( [](
auto& r,
auto& v) {
r -=
v; },
u); }
89 template<
typename U>
inline constexpr auto&
operator*=(U&& u) {
return apply_op_inplace( [](
auto& r,
auto& v) {
r *=
v; },
u); }
90 template<
typename U>
inline constexpr auto&
operator/=(U&& u) {
return apply_op_inplace( [](
auto& r,
auto& v) {
r /=
v; },
u); }
91 template<
typename U>
inline constexpr auto&
operator%=(U&& u) {
return apply_op_inplace( [](
auto& r,
auto& v) {
r %=
v; },
u); }
93 friend inline constexpr auto operator+(
const T& t,
const array_impl& a) {
return (a + t); }
94 friend inline constexpr auto operator-(
const T& t,
const array_impl& a) {
return (array<T,N>(t) - a); }
95 friend inline constexpr auto operator*(
const T& t,
const array_impl& a) {
return (a * t); }
96 friend inline constexpr auto operator/(
const T& t,
const array_impl& a) {
return (array<T,N>(t) / a); }
97 friend inline auto operator%(
const T& t,
const array_impl& a) {
return (array<T,N>(t) % a); }
101 template<
typename U>
inline constexpr auto operator&(U&& u)
const {
return apply_op( std::bit_and<>(), u); }
102 template<
typename U>
inline constexpr auto operator|(U&& u)
const {
return apply_op( std::bit_or<>(), u); }
103 template<
typename U>
inline constexpr auto operator^(U&& u)
const {
return apply_op( std::bit_xor<>(), u); }
104 inline constexpr auto operator~(
void)
const {
return apply_op( std::bit_not<>()); }
106 template<
typename U>
inline constexpr auto operator&=(U&& u) {
return apply_op_inplace( [](
auto& r,
auto& v) {
r &=
v; },
u); }
107 template<
typename U>
inline constexpr auto operator|=(U&& u) {
return apply_op_inplace( [](
auto& r,
auto& v) {
r |=
v; },
u); }
108 template<
typename U>
inline constexpr auto operator^=(U&& u) {
return apply_op_inplace( [](
auto& r,
auto& v) {
r ^=
v; },
u); }
110 friend inline constexpr auto operator|(
const T& t,
const array_impl& a) {
return (a | t); }
111 friend inline constexpr auto operator&(
const T& t,
const array_impl& a) {
return (a & t); }
112 friend inline constexpr auto operator^(
const T& t,
const array_impl& a) {
return (a ^ t); }
116 template<
typename U>
inline constexpr auto operator&&(U&& u)
const {
return apply_op( std::logical_and<>(), u); }
117 template<
typename U>
inline constexpr auto operator||(U&& u)
const {
return apply_op( std::logical_or<>(), u); }
118 inline constexpr auto operator!(
void)
const {
return apply_op( std::logical_not<>()); }
120 friend inline constexpr auto operator&&(
const T& t,
const array_impl& a) {
return (a && t); }
121 friend inline constexpr auto operator||(
const T& t,
const array_impl& a) {
return (a || t); }
125 template<
typename U>
inline constexpr auto operator<(U&& u)
const {
return apply_op( std::less<>(), u); }
126 template<
typename U>
inline constexpr auto operator<=(U&& u)
const {
return apply_op( std::less_equal<>(), u); }
127 template<
typename U>
inline constexpr auto operator>(U&& u)
const {
return apply_op( std::greater<>(), u); }
128 template<
typename U>
inline constexpr auto operator>=(U&& u)
const {
return apply_op( std::greater_equal<>(), u); }
130 friend inline constexpr auto operator<(
const T& t,
const array_impl& a) {
return (a > t); }
131 friend inline constexpr auto operator<=(
const T& t,
const array_impl& a) {
return (a >= t); }
132 friend inline constexpr auto operator>(
const T& t,
const array_impl& a) {
return (a < t); }
133 friend inline constexpr auto operator>=(
const T& t,
const array_impl& a) {
return (a <= t); }
135 template<
typename U>
friend inline constexpr bool operator==(
const array_impl& t,
const array_impl<U,N>& u) {
auto res = t.apply_op( std::equal_to<>(), u);
return std::all_of(res.begin(), res.end(), std::identity()); }
136 template<
typename U>
friend inline constexpr bool operator!=(
const array_impl& t,
const array_impl<U,N>& u) {
auto res = t.apply_op( std::equal_to<>(), u);
return std::none_of(res.begin(), res.end(), std::identity()); }
140 friend std::ostream&
operator<<(std::ostream& s,
const array_impl<T,N>& a)
145 if(&v != a.begin()) s <<
", ";
154 template<
typename... U,
typename OP>
155 inline auto apply_op(
const OP& op, U&&... u)
const
158 bbm::multirange_for([&](
auto& result,
auto&... arg) { result = op(arg...); }, result, *
this,
u...);
163 template<
typename... U,
typename OP>
164 inline auto& apply_op_inplace(
const OP& op, U&&... u)
176 template<
typename T,
size_t N>
requires (!std::is_reference_v<T>)
180 using base_type::base_type;
181 using base_type::operator=;
184 template<
typename T,
size_t N>
requires (std::is_reference_v<T>)
187 using base_type = detail::array_impl<bbm::reference<T>,N>;
188 using base_type::base_type;
189 using base_type::operator=;
196 template<
typename T>
struct is_array : std::false_type {};
197 template<
typename T,
size_t N>
struct is_array<array<T,N>> : std::true_type {};
204 using is_array = detail::is_array<std::decay_t<T>>;
212 template<
typename T>
struct array_size {
static constexpr size_t value = 1; };
213 template<
typename T,
size_t N>
struct array_size<
array<T,N>> {
static constexpr size_t value = N; };
221 static constexpr size_t array_size = detail::array_size< std::decay_t<T> >::value;
auto & operator--(T &a)
Definition: array.h:20
auto & operator++(T &a)
Definition: array.h:14
ranged for loop over multiple containers at once
Random number generator; built on top of Drjit.
Definition: backbone.h:53
static constexpr size_t array_size
array_size type traits
Definition: array.h:221
constexpr bool is_array_v
Definition: array.h:207
detail::is_array< std::decay_t< T > > is_array
Definition: array.h:204
constexpr decltype(auto) b(bbm::color< T > &c)
Definition: color.h:24
constexpr decltype(auto) r(bbm::color< T > &c)
Definition: color.h:18
constexpr decltype(auto) u(bbm::vec2d< T > &v)
Definition: vec.h:37
constexpr decltype(auto) v(bbm::vec2d< T > &v)
Definition: vec.h:40
auto operator/(const vector< T > &v, const U &u)
Definition: vector_util.h:273
constexpr FLAGNAME operator+(FLAGNAME a, FLAGNAME b)
Conact two flags.
Definition: flags.h:40
constexpr FLAGNAME & operator^=(FLAGNAME &a, FLAGNAME b)
Update 'a' with a^b,.
Definition: flags.h:92
constexpr FLAGNAME & operator+=(FLAGNAME &a, FLAGNAME b)
Update 'a' with a+b.
Definition: flags.h:84
constexpr FLAGNAME operator~(FLAGNAME a)
Set/unset flag that are unset/set respectively.
Definition: flags.h:61
auto & operator*=(vector< T > &v, const U &u)
Definition: vector_util.h:267
auto operator*(const vector< T > &v, const U &u)
Definition: vector_util.h:268
constexpr FLAGNAME & operator|=(FLAGNAME &a, FLAGNAME b)
Update 'a' with a | b.
Definition: flags.h:76
auto & operator/=(vector< T > &v, const U &u)
Definition: vector_util.h:272
void multirange_for(FUNC &&func, Ts &&... containers)
ranged for loop over multiple containers at once
Definition: multirange_for.h:43
constexpr FLAGNAME operator|(FLAGNAME a, FLAGNAME b)
Concat two flags.
Definition: flags.h:33
auto & operator%=(vector< T > &v, const U &u)
Definition: vector_util.h:276
std::ostream & operator<<(std::ostream &s, const BSDF &bsdf)
Definition: bsdf_base.h:138
auto end(T &&t)
Definition: iterator_util.h:43
constexpr FLAGNAME & operator&=(FLAGNAME &a, FLAGNAME b)
Update 'a' with a & b.
Definition: flags.h:68
auto operator%(const vector< T > &v, const U &u)
Definition: vector_util.h:277
constexpr FLAGNAME operator&(FLAGNAME a, FLAGNAME b)
Get the shared flags.
Definition: flags.h:47
auto begin(T &&t)
Definition: iterator_util.h:29
auto & operator-=(vector< T > &v, const U &u)
Definition: vector_util.h:263
constexpr FLAGNAME operator^(FLAGNAME a, FLAGNAME b)
Get the flags from 'a' that are not in 'b'.
Definition: flags.h:54
auto operator-(const vector< T > &v, const U &u)
Definition: vector_util.h:264
Assignable reference with wrapper support for rvalues.
detail::array_impl< T, N > base_type
Definition: array.h:179
Non-persistent reference (i.e., cannot take rvalues)
Definition: reference.h:86