libyggdrasil  v1.0.0
utils.hpp
Go to the documentation of this file.
1  /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2  * _____.___. .___ .__.__ *
3  * \__ | | ____ ____ __| _/___________ _____|__| | *
4  * / | |/ ___\ / ___\ / __ |\_ __ \__ \ / ___/ | | *
5  * \____ / /_/ > /_/ > /_/ | | | \// __ \_\___ \| | |__ *
6  * / ______\___ /\___ /\____ | |__| (____ /____ >__|____/ *
7  * \/ /_____//_____/ \/ \/ \/ *
8  * - Common - *
9  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
10  * This software can be used by students and other personal of the *
11  * Bern University of Applied Sciences under the terms of the MIT *
12  * license. *
13  * For other persons this software is under the terms of the GNU *
14  * General Public License version 2. *
15  * *
16  * Copyright © 2021, Bern University of Applied Sciences. *
17  * All rights reserved. *
18  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
26 #pragma once
27 
29 
30 #include <cstring> // memcpy
31 #include <type_traits> // Type trait checks
32 #include <utility>
33 
34 
35 #define TOKEN_CONCAT_IMPL(x, y) x ## y
36 #define TOKEN_CONCAT(x, y) TOKEN_CONCAT_IMPL(x, y)
37 #define ANONYMOUS_VARIABLE(prefix) TOKEN_CONCAT(prefix, __COUNTER__)
38 
39 
40 namespace bsp {
41 
45  template<typename T>
46  struct dependent_false : std::false_type {};
47 
48  template<typename T>
50 
51 
57  #define SCOPE_GUARD ::bsp::scope_guard::ScopeGuardOnExit() + [&]()
58 
64  #define ON_SCOPE_EXIT auto ANONYMOUS_VARIABLE(SCOPE_EXIT_) = SCOPE_GUARD
65 
66  namespace scope_guard {
67 
71  template<class F>
73  private:
74  F m_func;
75  bool m_active;
76  public:
77  constexpr ScopeGuardImpl(F func) : m_func(std::move(func)), m_active(true) { }
78  ~ScopeGuardImpl() { if (this->m_active) { this->m_func(); } }
79 
83  void release() { this->m_active = false; }
84 
85  ScopeGuardImpl(ScopeGuardImpl &&other) noexcept : m_func(std::move(other.m_func)), m_active(other.m_active) {
86  other.cancel();
87  }
88 
90  };
91 
92  enum class ScopeGuardOnExit { };
93 
97  template <typename F>
99  return ScopeGuardImpl<F>(std::forward<F>(f));
100  }
101 
102  }
103 
112  template <typename To, typename From>
113  To bit_cast(const From& src) noexcept {
114  return *reinterpret_cast<const To*>(&src);
115  }
116 
122  NO_RETURN ALWAYS_INLINE static void unreachable() {
123  __builtin_unreachable();
124  }
125 
131  template<typename T>
132  constexpr T byteSwap(T value) {
133  static_assert(std::is_integral<T>::value, "Only integral types can be byte swapped");
134  static_assert(sizeof(T) <= sizeof(u64), "Value cannot be bigger than 64 bit");
135 
136  if constexpr (sizeof(T) == 1) return value;
137  else if constexpr (sizeof(T) == 2) return __builtin_bswap16(value);
138  else if constexpr (sizeof(T) == 4) return __builtin_bswap32(value);
139  else if constexpr (sizeof(T) == 8) return __builtin_bswap64(value);
140  else bsp::unreachable();
141  }
142 
150  template<typename T>
151  auto enumValue(T value) {
152  static_assert(std::is_enum<T>::value, "Cannot get value of non-enum type");
153 
154  return static_cast<typename std::underlying_type<T>::type>(value);
155  }
156 
161  template<typename T>
163  constexpr ByteSwapped() : m_value(0) {}
164  constexpr ByteSwapped(T value) : m_value(byteSwap(value)) {}
165 
171  constexpr operator T() const noexcept {
172  return byteSwap(this->m_value);
173  }
174 
181  constexpr auto operator=(T value) {
182  this->m_value = byteSwap(value);
183 
184  return *this;
185  }
186 
193  constexpr auto operator=(const ByteSwapped &value) {
194  this->m_value = value.m_value;
195 
196  return *this;
197  }
198  private:
199  T m_value;
200  };
201 
207  ALWAYS_INLINE void doNotOptimize(const auto& value) {
208  asm volatile("" : : "r,m"(value) : "memory");
209  }
210 }
bsp::ByteSwapped::operator=
constexpr auto operator=(T value)
Transparently assign value and store it byte swapped.
Definition: utils.hpp:181
bsp::scope_guard::ScopeGuardImpl::ScopeGuardImpl
ScopeGuardImpl(ScopeGuardImpl &&other) noexcept
Definition: utils.hpp:85
bsp::ByteSwapped::ByteSwapped
constexpr ByteSwapped(T value)
Definition: utils.hpp:164
bsp::scope_guard::ScopeGuardImpl::release
void release()
Releases the scope guard and prevents it from being executed when going out of scope.
Definition: utils.hpp:83
bsp::ByteSwapped::operator=
constexpr auto operator=(const ByteSwapped &value)
Copy assignment operator.
Definition: utils.hpp:193
u64
uint64_t u64
Definition: types.h:39
ALWAYS_INLINE
#define ALWAYS_INLINE
Definition: attributes.h:34
NO_RETURN
#define NO_RETURN
Definition: attributes.h:31
PACKED
#define PACKED
Definition: attributes.h:35
bsp::enumValue
auto enumValue(T value)
Casts a scoped enum type into its underlying value.
Definition: utils.hpp:151
bsp::dependent_false_v
constexpr auto dependent_false_v
Definition: utils.hpp:49
bsp::ByteSwapped
Helper class to store the data of a given type in reverse order.
Definition: utils.hpp:162
bsp::bit_cast
To bit_cast(const From &src) noexcept
std::bit_cast implementation for doing reinterpret_cast-style conversion without invoking undefined b...
Definition: utils.hpp:113
bsp::scope_guard::ScopeGuardOnExit
ScopeGuardOnExit
Definition: utils.hpp:92
bsp::scope_guard::operator+
constexpr ScopeGuardImpl< F > operator+(ScopeGuardOnExit, F &&f)
Definition: utils.hpp:98
bsp::doNotOptimize
ALWAYS_INLINE void doNotOptimize(const auto &value)
Confuses the compiler to prevent it from optimizing out a variable. Helpful for debugging.
Definition: utils.hpp:207
bsp::scope_guard::ScopeGuardImpl::~ScopeGuardImpl
~ScopeGuardImpl()
Definition: utils.hpp:78
bsp::scope_guard::ScopeGuardImpl::operator=
ScopeGuardImpl & operator=(ScopeGuardImpl &&)=delete
bsp::ByteSwapped::ByteSwapped
constexpr ByteSwapped()
Definition: utils.hpp:163
bsp::dependent_false
Helper type trait for using static_asserts that should always trigger an error when evaluated.
Definition: utils.hpp:46
attributes.hpp
Commonly used C++ and GNU attributes.
bsp::byteSwap
constexpr T byteSwap(T value)
Swaps bytes of input value to convert between big and little endian.
Definition: utils.hpp:132
bsp
Definition: cortex.hpp:33
bsp::scope_guard::ScopeGuardImpl::ScopeGuardImpl
constexpr ScopeGuardImpl(F func)
Definition: utils.hpp:77
bsp::scope_guard::ScopeGuardImpl
Scope Guard implementation.
Definition: utils.hpp:72