BitStream
parameter.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include "assert.h"
4 
5 #include <utility>
6 #include <type_traits>
7 
8 #ifdef __cpp_constexpr_dynamic_alloc
9 #define BS_CONSTEXPR constexpr
10 #else // __cpp_constexpr_dynamic_alloc
11 #define BS_CONSTEXPR
12 #endif // __cpp_constexpr_dynamic_alloc
13 
14 namespace bitstream
15 {
16 #ifdef BS_DEBUG_BREAK
17  template<typename T>
18  class out
19  {
20  public:
21  BS_CONSTEXPR out(T& value) noexcept :
22  m_Value(value),
23  m_Constructed(false) {}
24 
25  out(const out&) = delete;
26 
27  out(out&&) = delete;
28 
29  BS_CONSTEXPR ~out()
30  {
31  if (!m_Constructed)
32  BS_BREAKPOINT();
33  }
34 
35  template<typename U, typename = std::enable_if_t<std::is_assignable_v<T&, U>>>
36  BS_CONSTEXPR out& operator=(U&& arg) noexcept(std::is_nothrow_assignable_v<T&, U>)
37  {
38  m_Value = std::forward<U>(arg);
39 
40  m_Constructed = true;
41 
42  return *this;
43  }
44 
45  BS_CONSTEXPR T* operator->() noexcept
46  {
47  m_Constructed = true;
48  return &m_Value;
49  }
50 
51  BS_CONSTEXPR T& operator*() noexcept
52  {
53  m_Constructed = true;
54  return m_Value;
55  }
56 
57  private:
58  T& m_Value;
59  bool m_Constructed;
60  };
61 #else
62  template<typename T>
63  class out
64  {
65  public:
66  BS_CONSTEXPR out(T& value) noexcept :
67  m_Value(value) {}
68 
69  out(const out&) = delete;
70 
71  out(out&&) = delete;
72 
73  template<typename U, typename = std::enable_if_t<std::is_assignable_v<T&, U>>>
74  BS_CONSTEXPR out& operator=(U&& arg) noexcept(std::is_nothrow_assignable_v<T&, U>)
75  {
76  m_Value = std::forward<U>(arg);
77 
78  return *this;
79  }
80 
81  BS_CONSTEXPR T* operator->() noexcept { return &m_Value; }
82 
83  BS_CONSTEXPR T& operator*() noexcept { return m_Value; }
84 
85  private:
86  T& m_Value;
87  };
88 #endif
89 
93  template<typename T>
94  using in = std::conditional_t<(sizeof(T) <= 16 && std::is_trivially_copy_constructible_v<T>), std::add_const_t<T>, std::add_lvalue_reference_t<std::add_const_t<T>>>;
95 
99  template<typename Stream, typename T>
100  using inout = std::conditional_t<Stream::writing, in<T>, std::add_lvalue_reference_t<T>>;
101 
102 
106  template<typename Lambda>
107  class finally
108  {
109  public:
110  constexpr finally(Lambda func) noexcept :
111  m_Lambda(func) {}
112 
114  {
115  m_Lambda();
116  }
117 
118  private:
119  Lambda m_Lambda;
120  };
121 
122  template<typename Lambda>
123  finally(Lambda func) -> finally<Lambda>;
124 }
#define BS_BREAKPOINT()
Definition: assert.h:17
Test type.
Definition: parameter.h:108
~finally()
Definition: parameter.h:113
Definition: parameter.h:64
out(out &&)=delete
BS_CONSTEXPR T & operator*() noexcept
Definition: parameter.h:83
BS_CONSTEXPR out & operator=(U &&arg) noexcept(std::is_nothrow_assignable_v< T &, U >)
Definition: parameter.h:74
out(const out &)=delete
BS_CONSTEXPR out(T &value) noexcept
Definition: parameter.h:66
BS_CONSTEXPR T * operator->() noexcept
Definition: parameter.h:81
Definition: bounded_range.h:28
std::conditional_t<(sizeof(T)<=16 &&std::is_trivially_copy_constructible_v< T >), std::add_const_t< T >, std::add_lvalue_reference_t< std::add_const_t< T > >> in
Passes by const or const reference depending on size.
Definition: parameter.h:94
std::conditional_t< Stream::writing, in< T >, std::add_lvalue_reference_t< T > > inout
Passes by reference.
Definition: parameter.h:100
#define BS_CONSTEXPR
Definition: parameter.h:11