1#ifndef _BBM_REFERENCE_H_
2#define _BBM_REFERENCE_H_
21 template<
typename T,
typename PTR=std::add_po
inter_t<std::remove_reference_t<T>>>
25 inline constexpr reference_impl(std::nullptr_t =
nullptr) noexcept : _ptr(
nullptr) {}
26 inline constexpr reference_impl(std::add_lvalue_reference_t<T> ref) noexcept : _ptr(std::addressof(ref)) {}
27 inline constexpr reference_impl(
const reference_impl& ref)
noexcept =
default;
31 inline constexpr reference_impl& operator=(
const reference_impl& ref)
noexcept =
default;
34 inline constexpr reference_impl& operator=(
const R& val)
37 std::add_lvalue_reference_t<T>(*
this) = val;
43 inline constexpr operator std::add_lvalue_reference_t<T>()
const
49 template<
typename TYPE>
requires std::constructible_from<TYPE, T>
50 inline constexpr operator TYPE(
void)
const
58 inline constexpr PTR operator->(
void)
const {
return _ptr; }
61 inline constexpr bool is_dereferenceable(
void)
const {
return (_ptr !=
nullptr); }
65 inline constexpr void reassign(R&& ref)
noexcept { *
this = reference_impl<T, PTR>(std::forward<R>(ref)); }
68 friend std::ostream&
operator<<(std::ostream& s,
const reference_impl<T,PTR>& ref)
70 if(ref.is_dereferenceable()) s << T(ref);
85 struct reference :
public bbm::detail::reference_impl<T, std::add_pointer_t<std::remove_reference_t<T>>>
87 using base_type = bbm::detail::reference_impl<T, std::add_pointer_t<std::remove_reference_t<T>>>;
88 using base_type::base_type;
89 using base_type::operator=;
92 inline constexpr reference(std::decay_t<T>&& ) =
delete;
105 template<
typename T>
requires (!bbm::is_const_v<T>)
115 template<
typename T>
requires bbm::is_const_v<T>
118 using base_type = bbm::detail::reference_impl<T, bbm::pointer<T>>;
119 using base_type::base_type;
120 using base_type::operator=;
128 template<
typename R>
requires (!std::is_same_v<persistent_reference<T>, std::decay_t<R>>) &&
129 ((std::is_rvalue_reference_v<R&&> && std::same_as<std::remove_cvref_t<R>, std::remove_cvref_t<T>>) ||
130 (std::constructible_from<std::remove_reference_t<T>, R> && !std::same_as<std::remove_cvref_t<R>, std::remove_cvref_t<T>>))
133 base_type::_ptr = std::make_shared<std::remove_reference_t<T>>(std::forward<R>(val));
144 template<
typename T>
struct is_bbm_reference_impl : std::false_type {};
145 template<
typename T,
typename PTR>
struct is_bbm_reference_impl<reference_impl<T,PTR>> : std::true_type {};
Predefined exceptions for common errors.
#define bbm_unassigned_ref
Definition: error.h:43
#define BBM_CONST_ASSIGNMENT
Definition: error.h:54
Definition: aggregatebsdf.h:29
std::ostream & operator<<(std::ostream &s, const BSDF &bsdf)
Definition: bsdf_base.h:138
constexpr bool is_bbm_reference_v
Definition: reference.h:155
bbm::detail::is_bbm_reference_impl< std::decay_t< T > > is_bbm_reference
Definition: reference.h:152
Declaration of persistent_reference specialized below.
Definition: reference.h:100
Pointer wrapper that takes both shared and non-shared pointers. If the pointer is 'managed' then the ...
constexpr persistent_reference(R &&val) noexcept
Handle assignment to a const reference of a temporary variable => make_pointer This occurs if: 1) R !...
Definition: reference.h:131
bbm::detail::reference_impl< T, bbm::pointer< T > > base_type
Definition: reference.h:118
Non-persistent reference (i.e., cannot take rvalues)
Definition: reference.h:86
constexpr reference(std::decay_t< T > &&)=delete
Disallow rvalue construction.
bbm::detail::reference_impl< T, std::add_pointer_t< std::remove_reference_t< T > > > base_type
Definition: reference.h:87