mcl: clang-format: Adopt WebKit style bracing

This commit is contained in:
Merry 2022-04-26 12:16:55 +01:00
parent d5a46fa705
commit 416a2c6b56
13 changed files with 174 additions and 93 deletions

View File

@ -34,7 +34,7 @@ BraceWrapping:
AfterClass: false AfterClass: false
AfterControlStatement: Never AfterControlStatement: Never
AfterEnum: false AfterEnum: false
AfterFunction: false AfterFunction: true
AfterNamespace: false AfterNamespace: false
AfterObjCDeclaration: false AfterObjCDeclaration: false
AfterStruct: false AfterStruct: false
@ -62,7 +62,7 @@ ColumnLimit: 0
CommentPragmas: '^ IWYU pragma:' CommentPragmas: '^ IWYU pragma:'
CompactNamespaces: false CompactNamespaces: false
ConstructorInitializerAllOnOneLineOrOnePerLine: true ConstructorInitializerAllOnOneLineOrOnePerLine: true
ConstructorInitializerIndentWidth: 8 ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4 ContinuationIndentWidth: 4
Cpp11BracedListStyle: true Cpp11BracedListStyle: true
DeriveLineEnding: true DeriveLineEnding: true

View File

@ -16,7 +16,8 @@ namespace mcl::detail {
[[noreturn]] void assert_terminate_impl(fmt::string_view msg, fmt::format_args args); [[noreturn]] void assert_terminate_impl(fmt::string_view msg, fmt::format_args args);
template<typename... Ts> template<typename... Ts>
[[noreturn]] void assert_terminate(fmt::string_view msg, Ts... args) { [[noreturn]] void assert_terminate(fmt::string_view msg, Ts... args)
{
assert_terminate_impl(msg, fmt::make_format_args(args...)); assert_terminate_impl(msg, fmt::make_format_args(args...));
} }

View File

@ -13,12 +13,14 @@
namespace mcl::bit { namespace mcl::bit {
template<BitIntegral T> template<BitIntegral T>
inline size_t count_ones(T x) { inline size_t count_ones(T x)
{
return std::bitset<bitsizeof<T>>(x).count(); return std::bitset<bitsizeof<T>>(x).count();
} }
template<BitIntegral T> template<BitIntegral T>
constexpr size_t count_leading_zeros(T x) { constexpr size_t count_leading_zeros(T x)
{
size_t result = bitsizeof<T>; size_t result = bitsizeof<T>;
while (x != 0) { while (x != 0) {
x >>= 1; x >>= 1;
@ -28,7 +30,8 @@ constexpr size_t count_leading_zeros(T x) {
} }
template<BitIntegral T> template<BitIntegral T>
constexpr int highest_set_bit(T x) { constexpr int highest_set_bit(T x)
{
int result = -1; int result = -1;
while (x != 0) { while (x != 0) {
x >>= 1; x >>= 1;
@ -38,7 +41,8 @@ constexpr int highest_set_bit(T x) {
} }
template<BitIntegral T> template<BitIntegral T>
constexpr size_t lowest_set_bit(T x) { constexpr size_t lowest_set_bit(T x)
{
if (x == 0) { if (x == 0) {
return bitsizeof<T>; return bitsizeof<T>;
} }

View File

@ -13,7 +13,8 @@ namespace mcl::bit {
/// Create a mask with `count` number of one bits. /// Create a mask with `count` number of one bits.
template<size_t count, BitIntegral T> template<size_t count, BitIntegral T>
constexpr T ones() { constexpr T ones()
{
static_assert(count <= bitsizeof<T>, "count larger than bitsize of T"); static_assert(count <= bitsizeof<T>, "count larger than bitsize of T");
if constexpr (count == 0) { if constexpr (count == 0) {
@ -25,7 +26,8 @@ constexpr T ones() {
/// Create a mask with `count` number of one bits. /// Create a mask with `count` number of one bits.
template<BitIntegral T> template<BitIntegral T>
constexpr T ones(size_t count) { constexpr T ones(size_t count)
{
ASSERT_MSG(count <= bitsizeof<T>, "count larger than bitsize of T"); ASSERT_MSG(count <= bitsizeof<T>, "count larger than bitsize of T");
if (count == 0) { if (count == 0) {
@ -36,7 +38,8 @@ constexpr T ones(size_t count) {
/// Create a mask of type T for bits [begin_bit, end_bit] inclusive. /// Create a mask of type T for bits [begin_bit, end_bit] inclusive.
template<size_t begin_bit, size_t end_bit, BitIntegral T> template<size_t begin_bit, size_t end_bit, BitIntegral T>
constexpr T mask() { constexpr T mask()
{
static_assert(begin_bit <= end_bit, "invalid bit range (position of beginning bit cannot be greater than that of end bit)"); static_assert(begin_bit <= end_bit, "invalid bit range (position of beginning bit cannot be greater than that of end bit)");
static_assert(begin_bit < bitsizeof<T>, "begin_bit must be smaller than size of T"); static_assert(begin_bit < bitsizeof<T>, "begin_bit must be smaller than size of T");
static_assert(end_bit < bitsizeof<T>, "end_bit must be smaller than size of T"); static_assert(end_bit < bitsizeof<T>, "end_bit must be smaller than size of T");
@ -46,7 +49,8 @@ constexpr T mask() {
/// Create a mask of type T for bits [begin_bit, end_bit] inclusive. /// Create a mask of type T for bits [begin_bit, end_bit] inclusive.
template<BitIntegral T> template<BitIntegral T>
constexpr T mask(size_t begin_bit, size_t end_bit) { constexpr T mask(size_t begin_bit, size_t end_bit)
{
ASSERT_MSG(begin_bit <= end_bit, "invalid bit range (position of beginning bit cannot be greater than that of end bit)"); ASSERT_MSG(begin_bit <= end_bit, "invalid bit range (position of beginning bit cannot be greater than that of end bit)");
ASSERT_MSG(begin_bit < bitsizeof<T>, "begin_bit must be smaller than size of T"); ASSERT_MSG(begin_bit < bitsizeof<T>, "begin_bit must be smaller than size of T");
ASSERT_MSG(end_bit < bitsizeof<T>, "end_bit must be smaller than size of T"); ASSERT_MSG(end_bit < bitsizeof<T>, "end_bit must be smaller than size of T");
@ -56,91 +60,104 @@ constexpr T mask(size_t begin_bit, size_t end_bit) {
/// Extract bits [begin_bit, end_bit] inclusive from value of type T. /// Extract bits [begin_bit, end_bit] inclusive from value of type T.
template<size_t begin_bit, size_t end_bit, BitIntegral T> template<size_t begin_bit, size_t end_bit, BitIntegral T>
constexpr T get_bits(T value) { constexpr T get_bits(T value)
{
constexpr T m = mask<begin_bit, end_bit, T>(); constexpr T m = mask<begin_bit, end_bit, T>();
return (value & m) >> begin_bit; return (value & m) >> begin_bit;
} }
/// Extract bits [begin_bit, end_bit] inclusive from value of type T. /// Extract bits [begin_bit, end_bit] inclusive from value of type T.
template<BitIntegral T> template<BitIntegral T>
constexpr T get_bits(size_t begin_bit, size_t end_bit, T value) { constexpr T get_bits(size_t begin_bit, size_t end_bit, T value)
{
const T m = mask<T>(begin_bit, end_bit); const T m = mask<T>(begin_bit, end_bit);
return (value & m) >> begin_bit; return (value & m) >> begin_bit;
} }
/// Clears bits [begin_bit, end_bit] inclusive of value of type T. /// Clears bits [begin_bit, end_bit] inclusive of value of type T.
template<size_t begin_bit, size_t end_bit, BitIntegral T> template<size_t begin_bit, size_t end_bit, BitIntegral T>
constexpr T clear_bits(T value) { constexpr T clear_bits(T value)
{
constexpr T m = mask<begin_bit, end_bit, T>(); constexpr T m = mask<begin_bit, end_bit, T>();
return value & ~m; return value & ~m;
} }
/// Clears bits [begin_bit, end_bit] inclusive of value of type T. /// Clears bits [begin_bit, end_bit] inclusive of value of type T.
template<BitIntegral T> template<BitIntegral T>
constexpr T clear_bits(size_t begin_bit, size_t end_bit, T value) { constexpr T clear_bits(size_t begin_bit, size_t end_bit, T value)
{
const T m = mask<T>(begin_bit, end_bit); const T m = mask<T>(begin_bit, end_bit);
return value & ~m; return value & ~m;
} }
/// Modifies bits [begin_bit, end_bit] inclusive of value of type T. /// Modifies bits [begin_bit, end_bit] inclusive of value of type T.
template<size_t begin_bit, size_t end_bit, BitIntegral T> template<size_t begin_bit, size_t end_bit, BitIntegral T>
constexpr T set_bits(T value, T new_bits) { constexpr T set_bits(T value, T new_bits)
{
constexpr T m = mask<begin_bit, end_bit, T>(); constexpr T m = mask<begin_bit, end_bit, T>();
return (value & ~m) | ((new_bits << begin_bit) & m); return (value & ~m) | ((new_bits << begin_bit) & m);
} }
/// Modifies bits [begin_bit, end_bit] inclusive of value of type T. /// Modifies bits [begin_bit, end_bit] inclusive of value of type T.
template<BitIntegral T> template<BitIntegral T>
constexpr T set_bits(size_t begin_bit, size_t end_bit, T value, T new_bits) { constexpr T set_bits(size_t begin_bit, size_t end_bit, T value, T new_bits)
{
const T m = mask<T>(begin_bit, end_bit); const T m = mask<T>(begin_bit, end_bit);
return (value & ~m) | ((new_bits << begin_bit) & m); return (value & ~m) | ((new_bits << begin_bit) & m);
} }
/// Extract bit at bit_position from value of type T. /// Extract bit at bit_position from value of type T.
template<size_t bit_position, BitIntegral T> template<size_t bit_position, BitIntegral T>
constexpr bool get_bit(T value) { constexpr bool get_bit(T value)
{
constexpr T m = mask<bit_position, bit_position, T>(); constexpr T m = mask<bit_position, bit_position, T>();
return (value & m) != 0; return (value & m) != 0;
} }
/// Extract bit at bit_position from value of type T. /// Extract bit at bit_position from value of type T.
template<BitIntegral T> template<BitIntegral T>
constexpr bool get_bit(size_t bit_position, T value) { constexpr bool get_bit(size_t bit_position, T value)
{
const T m = mask<T>(bit_position, bit_position); const T m = mask<T>(bit_position, bit_position);
return (value & m) != 0; return (value & m) != 0;
} }
/// Clears bit at bit_position of value of type T. /// Clears bit at bit_position of value of type T.
template<size_t bit_position, BitIntegral T> template<size_t bit_position, BitIntegral T>
constexpr T clear_bit(T value) { constexpr T clear_bit(T value)
{
constexpr T m = mask<bit_position, bit_position, T>(); constexpr T m = mask<bit_position, bit_position, T>();
return value & ~m; return value & ~m;
} }
/// Clears bit at bit_position of value of type T. /// Clears bit at bit_position of value of type T.
template<BitIntegral T> template<BitIntegral T>
constexpr T clear_bit(size_t bit_position, T value) { constexpr T clear_bit(size_t bit_position, T value)
{
const T m = mask<T>(bit_position, bit_position); const T m = mask<T>(bit_position, bit_position);
return value & ~m; return value & ~m;
} }
/// Modifies bit at bit_position of value of type T. /// Modifies bit at bit_position of value of type T.
template<size_t bit_position, BitIntegral T> template<size_t bit_position, BitIntegral T>
constexpr T set_bit(T value, bool new_bit) { constexpr T set_bit(T value, bool new_bit)
{
constexpr T m = mask<bit_position, bit_position, T>(); constexpr T m = mask<bit_position, bit_position, T>();
return (value & ~m) | (new_bit ? m : static_cast<T>(0)); return (value & ~m) | (new_bit ? m : static_cast<T>(0));
} }
/// Modifies bit at bit_position of value of type T. /// Modifies bit at bit_position of value of type T.
template<BitIntegral T> template<BitIntegral T>
constexpr T set_bit(size_t bit_position, T value, bool new_bit) { constexpr T set_bit(size_t bit_position, T value, bool new_bit)
{
const T m = mask<T>(bit_position, bit_position); const T m = mask<T>(bit_position, bit_position);
return (value & ~m) | (new_bit ? m : static_cast<T>(0)); return (value & ~m) | (new_bit ? m : static_cast<T>(0));
} }
/// Sign-extends a value that has bit_count bits to the full bitwidth of type T. /// Sign-extends a value that has bit_count bits to the full bitwidth of type T.
template<size_t bit_count, BitIntegral T> template<size_t bit_count, BitIntegral T>
constexpr T sign_extend(T value) { constexpr T sign_extend(T value)
{
static_assert(bit_count != 0, "cannot sign-extend zero-sized value"); static_assert(bit_count != 0, "cannot sign-extend zero-sized value");
using S = std::make_signed_t<T>; using S = std::make_signed_t<T>;
@ -150,7 +167,8 @@ constexpr T sign_extend(T value) {
/// Sign-extends a value that has bit_count bits to the full bitwidth of type T. /// Sign-extends a value that has bit_count bits to the full bitwidth of type T.
template<BitIntegral T> template<BitIntegral T>
constexpr T sign_extend(size_t bit_count, T value) { constexpr T sign_extend(size_t bit_count, T value)
{
ASSERT_MSG(bit_count != 0, "cannot sign-extend zero-sized value"); ASSERT_MSG(bit_count != 0, "cannot sign-extend zero-sized value");
using S = std::make_signed_t<T>; using S = std::make_signed_t<T>;
@ -160,7 +178,8 @@ constexpr T sign_extend(size_t bit_count, T value) {
/// Replicate an element across a value of type T. /// Replicate an element across a value of type T.
template<size_t element_size, BitIntegral T> template<size_t element_size, BitIntegral T>
constexpr T replicate_element(T value) { constexpr T replicate_element(T value)
{
static_assert(element_size <= bitsizeof<T>, "element_size is too large"); static_assert(element_size <= bitsizeof<T>, "element_size is too large");
static_assert(bitsizeof<T> % element_size == 0, "bitsize of T not divisible by element_size"); static_assert(bitsizeof<T> % element_size == 0, "bitsize of T not divisible by element_size");
@ -173,7 +192,8 @@ constexpr T replicate_element(T value) {
/// Replicate an element of type U across a value of type T. /// Replicate an element of type U across a value of type T.
template<BitIntegral U, BitIntegral T> template<BitIntegral U, BitIntegral T>
constexpr T replicate_element(T value) { constexpr T replicate_element(T value)
{
static_assert(bitsizeof<U> <= bitsizeof<T>, "element_size is too large"); static_assert(bitsizeof<U> <= bitsizeof<T>, "element_size is too large");
return replicate_element<bitsizeof<U>, T>(value); return replicate_element<bitsizeof<U>, T>(value);
@ -181,7 +201,8 @@ constexpr T replicate_element(T value) {
/// Replicate an element across a value of type T. /// Replicate an element across a value of type T.
template<BitIntegral T> template<BitIntegral T>
constexpr T replicate_element(size_t element_size, T value) { constexpr T replicate_element(size_t element_size, T value)
{
ASSERT_MSG(element_size <= bitsizeof<T>, "element_size is too large"); ASSERT_MSG(element_size <= bitsizeof<T>, "element_size is too large");
ASSERT_MSG(bitsizeof<T> % element_size == 0, "bitsize of T not divisible by element_size"); ASSERT_MSG(bitsizeof<T> % element_size == 0, "bitsize of T not divisible by element_size");
@ -192,7 +213,8 @@ constexpr T replicate_element(size_t element_size, T value) {
} }
template<BitIntegral T> template<BitIntegral T>
constexpr bool most_significant_bit(T value) { constexpr bool most_significant_bit(T value)
{
return get_bit<bitsizeof<T> - 1, T>(value); return get_bit<bitsizeof<T> - 1, T>(value);
} }

View File

@ -11,7 +11,8 @@
namespace mcl::bit { namespace mcl::bit {
template<BitIntegral T> template<BitIntegral T>
constexpr T rotate_right(T x, size_t amount) { constexpr T rotate_right(T x, size_t amount)
{
amount %= bitsizeof<T>; amount %= bitsizeof<T>;
if (amount == 0) { if (amount == 0) {
return x; return x;
@ -20,7 +21,8 @@ constexpr T rotate_right(T x, size_t amount) {
} }
template<BitIntegral T> template<BitIntegral T>
constexpr T rotate_left(T x, size_t amount) { constexpr T rotate_left(T x, size_t amount)
{
amount %= bitsizeof<T>; amount %= bitsizeof<T>;
if (amount == 0) { if (amount == 0) {
return x; return x;

View File

@ -8,18 +8,21 @@
namespace mcl::bit { namespace mcl::bit {
constexpr u16 swap_bytes_16(u16 value) { constexpr u16 swap_bytes_16(u16 value)
{
return static_cast<u16>(u32{value} >> 8 | u32{value} << 8); return static_cast<u16>(u32{value} >> 8 | u32{value} << 8);
} }
constexpr u32 swap_bytes_32(u32 value) { constexpr u32 swap_bytes_32(u32 value)
{
return ((value & 0xff000000u) >> 24) return ((value & 0xff000000u) >> 24)
| ((value & 0x00ff0000u) >> 8) | ((value & 0x00ff0000u) >> 8)
| ((value & 0x0000ff00u) << 8) | ((value & 0x0000ff00u) << 8)
| ((value & 0x000000ffu) << 24); | ((value & 0x000000ffu) << 24);
} }
constexpr u64 swap_bytes_64(u64 value) { constexpr u64 swap_bytes_64(u64 value)
{
return ((value & 0xff00000000000000ull) >> 56) return ((value & 0xff00000000000000ull) >> 56)
| ((value & 0x00ff000000000000ull) >> 40) | ((value & 0x00ff000000000000ull) >> 40)
| ((value & 0x0000ff0000000000ull) >> 24) | ((value & 0x0000ff0000000000ull) >> 24)
@ -30,19 +33,22 @@ constexpr u64 swap_bytes_64(u64 value) {
| ((value & 0x00000000000000ffull) << 56); | ((value & 0x00000000000000ffull) << 56);
} }
constexpr u32 swap_halves_32(u32 value) { constexpr u32 swap_halves_32(u32 value)
{
return ((value & 0xffff0000u) >> 16) return ((value & 0xffff0000u) >> 16)
| ((value & 0x0000ffffu) << 16); | ((value & 0x0000ffffu) << 16);
} }
constexpr u64 swap_halves_64(u64 value) { constexpr u64 swap_halves_64(u64 value)
{
return ((value & 0xffff000000000000ull) >> 48) return ((value & 0xffff000000000000ull) >> 48)
| ((value & 0x0000ffff00000000ull) >> 16) | ((value & 0x0000ffff00000000ull) >> 16)
| ((value & 0x00000000ffff0000ull) << 16) | ((value & 0x00000000ffff0000ull) << 16)
| ((value & 0x000000000000ffffull) << 48); | ((value & 0x000000000000ffffull) << 48);
} }
constexpr u64 swap_words_64(u64 value) { constexpr u64 swap_words_64(u64 value)
{
return ((value & 0xffffffff00000000ull) >> 32) return ((value & 0xffffffff00000000ull) >> 32)
| ((value & 0x00000000ffffffffull) << 32); | ((value & 0x00000000ffffffffull) << 32);
} }

View File

@ -11,7 +11,8 @@ namespace mcl {
/// Reinterpret objects of one type as another by bit-casting between object representations. /// Reinterpret objects of one type as another by bit-casting between object representations.
template<class Dest, class Source> template<class Dest, class Source>
inline Dest bit_cast(const Source& source) noexcept { inline Dest bit_cast(const Source& source) noexcept
{
static_assert(sizeof(Dest) == sizeof(Source), "size of destination and source objects must be equal"); static_assert(sizeof(Dest) == sizeof(Source), "size of destination and source objects must be equal");
static_assert(std::is_trivially_copyable_v<Dest>, "destination type must be trivially copyable."); static_assert(std::is_trivially_copyable_v<Dest>, "destination type must be trivially copyable.");
static_assert(std::is_trivially_copyable_v<Source>, "source type must be trivially copyable"); static_assert(std::is_trivially_copyable_v<Source>, "source type must be trivially copyable");
@ -24,7 +25,8 @@ inline Dest bit_cast(const Source& source) noexcept {
/// Reinterpret objects of any arbitrary type as another type by bit-casting between object representations. /// Reinterpret objects of any arbitrary type as another type by bit-casting between object representations.
/// Note that here we do not verify if source pointed to by source_ptr has enough bytes to read from. /// Note that here we do not verify if source pointed to by source_ptr has enough bytes to read from.
template<class Dest, class SourcePtr> template<class Dest, class SourcePtr>
inline Dest bit_cast_pointee(const SourcePtr source_ptr) noexcept { inline Dest bit_cast_pointee(const SourcePtr source_ptr) noexcept
{
static_assert(sizeof(SourcePtr) == sizeof(void*), "source pointer must have size of a pointer"); static_assert(sizeof(SourcePtr) == sizeof(void*), "source pointer must have size of a pointer");
static_assert(std::is_trivially_copyable_v<Dest>, "destination type must be trivially copyable."); static_assert(std::is_trivially_copyable_v<Dest>, "destination type must be trivially copyable.");

View File

@ -21,7 +21,8 @@ class intrusive_list_iterator;
template<typename T> template<typename T>
class intrusive_list_node { class intrusive_list_node {
public: public:
bool is_sentinel() const { bool is_sentinel() const
{
return is_sentinel_; return is_sentinel_;
} }
@ -42,7 +43,8 @@ class intrusive_list_sentinel final : public intrusive_list_node<T> {
using intrusive_list_node<T>::is_sentinel_; using intrusive_list_node<T>::is_sentinel_;
public: public:
intrusive_list_sentinel() { intrusive_list_sentinel()
{
next = this; next = this;
prev = this; prev = this;
is_sentinel_ = true; is_sentinel_ = true;
@ -72,50 +74,56 @@ public:
intrusive_list_iterator& operator=(const intrusive_list_iterator& other) = default; intrusive_list_iterator& operator=(const intrusive_list_iterator& other) = default;
explicit intrusive_list_iterator(node_pointer list_node) explicit intrusive_list_iterator(node_pointer list_node)
: node(list_node) { : node(list_node) {}
}
explicit intrusive_list_iterator(pointer data) explicit intrusive_list_iterator(pointer data)
: node(data) { : node(data) {}
}
explicit intrusive_list_iterator(reference data) explicit intrusive_list_iterator(reference data)
: node(&data) { : node(&data) {}
}
intrusive_list_iterator& operator++() { intrusive_list_iterator& operator++()
{
node = node->next; node = node->next;
return *this; return *this;
} }
intrusive_list_iterator& operator--() { intrusive_list_iterator& operator--()
{
node = node->prev; node = node->prev;
return *this; return *this;
} }
intrusive_list_iterator operator++(int) { intrusive_list_iterator operator++(int)
{
intrusive_list_iterator it(*this); intrusive_list_iterator it(*this);
++*this; ++*this;
return it; return it;
} }
intrusive_list_iterator operator--(int) { intrusive_list_iterator operator--(int)
{
intrusive_list_iterator it(*this); intrusive_list_iterator it(*this);
--*this; --*this;
return it; return it;
} }
bool operator==(const intrusive_list_iterator& other) const { bool operator==(const intrusive_list_iterator& other) const
{
return node == other.node; return node == other.node;
} }
bool operator!=(const intrusive_list_iterator& other) const { bool operator!=(const intrusive_list_iterator& other) const
{
return !operator==(other); return !operator==(other);
} }
reference operator*() const { reference operator*() const
{
DEBUG_ASSERT(!node->is_sentinel()); DEBUG_ASSERT(!node->is_sentinel());
return static_cast<reference>(*node); return static_cast<reference>(*node);
} }
pointer operator->() const { pointer operator->() const
{
return std::addressof(operator*()); return std::addressof(operator*());
} }
node_pointer AsNodePointer() const { node_pointer AsNodePointer() const
{
return node; return node;
} }
@ -145,7 +153,8 @@ public:
* @param location The location to insert the node. * @param location The location to insert the node.
* @param new_node The node to add. * @param new_node The node to add.
*/ */
iterator insert(iterator location, pointer new_node) { iterator insert(iterator location, pointer new_node)
{
return insert_before(location, new_node); return insert_before(location, new_node);
} }
@ -156,7 +165,8 @@ public:
* @param location The location to insert the new node. * @param location The location to insert the new node.
* @param new_node The node to insert into the list. * @param new_node The node to insert into the list.
*/ */
iterator insert_before(iterator location, pointer new_node) { iterator insert_before(iterator location, pointer new_node)
{
auto existing_node = location.AsNodePointer(); auto existing_node = location.AsNodePointer();
new_node->next = existing_node; new_node->next = existing_node;
@ -173,7 +183,8 @@ public:
* @param position Location to insert the node in front of. * @param position Location to insert the node in front of.
* @param new_node The node to be inserted into the list. * @param new_node The node to be inserted into the list.
*/ */
iterator insert_after(iterator position, pointer new_node) { iterator insert_after(iterator position, pointer new_node)
{
if (empty()) if (empty())
return insert(begin(), new_node); return insert(begin(), new_node);
@ -184,7 +195,8 @@ public:
* Add an entry to the start of the list. * Add an entry to the start of the list.
* @param node Node to add to the list. * @param node Node to add to the list.
*/ */
void push_front(pointer node) { void push_front(pointer node)
{
insert(begin(), node); insert(begin(), node);
} }
@ -192,7 +204,8 @@ public:
* Add an entry to the end of the list * Add an entry to the end of the list
* @param node Node to add to the list. * @param node Node to add to the list.
*/ */
void push_back(pointer node) { void push_back(pointer node)
{
insert(end(), node); insert(end(), node);
} }
@ -200,7 +213,8 @@ public:
* Erases the node at the front of the list. * Erases the node at the front of the list.
* @note Must not be called on an empty list. * @note Must not be called on an empty list.
*/ */
void pop_front() { void pop_front()
{
DEBUG_ASSERT(!empty()); DEBUG_ASSERT(!empty());
erase(begin()); erase(begin());
} }
@ -209,7 +223,8 @@ public:
* Erases the node at the back of the list. * Erases the node at the back of the list.
* @note Must not be called on an empty list. * @note Must not be called on an empty list.
*/ */
void pop_back() { void pop_back()
{
DEBUG_ASSERT(!empty()); DEBUG_ASSERT(!empty());
erase(--end()); erase(--end());
} }
@ -218,7 +233,8 @@ public:
* Removes a node from this list * Removes a node from this list
* @param it An iterator that points to the node to remove from list. * @param it An iterator that points to the node to remove from list.
*/ */
pointer remove(iterator& it) { pointer remove(iterator& it)
{
DEBUG_ASSERT(it != end()); DEBUG_ASSERT(it != end());
pointer node = &*it++; pointer node = &*it++;
@ -237,7 +253,8 @@ public:
* Removes a node from this list * Removes a node from this list
* @param it A constant iterator that points to the node to remove from list. * @param it A constant iterator that points to the node to remove from list.
*/ */
pointer remove(const iterator& it) { pointer remove(const iterator& it)
{
iterator copy = it; iterator copy = it;
return remove(copy); return remove(copy);
} }
@ -246,7 +263,8 @@ public:
* Removes a node from this list. * Removes a node from this list.
* @param node A pointer to the node to remove. * @param node A pointer to the node to remove.
*/ */
pointer remove(pointer node) { pointer remove(pointer node)
{
return remove(iterator(node)); return remove(iterator(node));
} }
@ -254,7 +272,8 @@ public:
* Removes a node from this list. * Removes a node from this list.
* @param node A reference to the node to remove. * @param node A reference to the node to remove.
*/ */
pointer remove(reference node) { pointer remove(reference node)
{
return remove(iterator(node)); return remove(iterator(node));
} }
@ -262,7 +281,8 @@ public:
* Is this list empty? * Is this list empty?
* @returns true if there are no nodes in this list. * @returns true if there are no nodes in this list.
*/ */
bool empty() const { bool empty() const
{
return root->next == root.get(); return root->next == root.get();
} }
@ -270,7 +290,8 @@ public:
* Gets the total number of elements within this list. * Gets the total number of elements within this list.
* @return the number of elements in this list. * @return the number of elements in this list.
*/ */
size_type size() const { size_type size() const
{
return static_cast<size_type>(std::distance(begin(), end())); return static_cast<size_type>(std::distance(begin(), end()));
} }
@ -278,7 +299,8 @@ public:
* Retrieves a reference to the node at the front of the list. * Retrieves a reference to the node at the front of the list.
* @note Must not be called on an empty list. * @note Must not be called on an empty list.
*/ */
reference front() { reference front()
{
DEBUG_ASSERT(!empty()); DEBUG_ASSERT(!empty());
return *begin(); return *begin();
} }
@ -287,7 +309,8 @@ public:
* Retrieves a constant reference to the node at the front of the list. * Retrieves a constant reference to the node at the front of the list.
* @note Must not be called on an empty list. * @note Must not be called on an empty list.
*/ */
const_reference front() const { const_reference front() const
{
DEBUG_ASSERT(!empty()); DEBUG_ASSERT(!empty());
return *begin(); return *begin();
} }
@ -296,7 +319,8 @@ public:
* Retrieves a reference to the node at the back of the list. * Retrieves a reference to the node at the back of the list.
* @note Must not be called on an empty list. * @note Must not be called on an empty list.
*/ */
reference back() { reference back()
{
DEBUG_ASSERT(!empty()); DEBUG_ASSERT(!empty());
return *--end(); return *--end();
} }
@ -305,7 +329,8 @@ public:
* Retrieves a constant reference to the node at the back of the list. * Retrieves a constant reference to the node at the back of the list.
* @note Must not be called on an empty list. * @note Must not be called on an empty list.
*/ */
const_reference back() const { const_reference back() const
{
DEBUG_ASSERT(!empty()); DEBUG_ASSERT(!empty());
return *--end(); return *--end();
} }
@ -331,7 +356,8 @@ public:
* Erases a node from the list, indicated by an iterator. * Erases a node from the list, indicated by an iterator.
* @param it The iterator that points to the node to erase. * @param it The iterator that points to the node to erase.
*/ */
iterator erase(iterator it) { iterator erase(iterator it)
{
remove(it); remove(it);
return it; return it;
} }
@ -340,7 +366,8 @@ public:
* Erases a node from this list. * Erases a node from this list.
* @param node A pointer to the node to erase from this list. * @param node A pointer to the node to erase from this list.
*/ */
iterator erase(pointer node) { iterator erase(pointer node)
{
return erase(iterator(node)); return erase(iterator(node));
} }
@ -348,7 +375,8 @@ public:
* Erases a node from this list. * Erases a node from this list.
* @param node A reference to the node to erase from this list. * @param node A reference to the node to erase from this list.
*/ */
iterator erase(reference node) { iterator erase(reference node)
{
return erase(iterator(node)); return erase(iterator(node));
} }
@ -356,7 +384,8 @@ public:
* Exchanges contents of this list with another list instance. * Exchanges contents of this list with another list instance.
* @param other The other list to swap with. * @param other The other list to swap with.
*/ */
void swap(intrusive_list& other) noexcept { void swap(intrusive_list& other) noexcept
{
root.swap(other.root); root.swap(other.root);
} }
@ -371,7 +400,8 @@ private:
* @param rhs The second list. * @param rhs The second list.
*/ */
template<typename T> template<typename T>
void swap(intrusive_list<T>& lhs, intrusive_list<T>& rhs) noexcept { void swap(intrusive_list<T>& lhs, intrusive_list<T>& rhs) noexcept
{
lhs.swap(rhs); lhs.swap(rhs);
} }

View File

@ -13,12 +13,14 @@ template<typename T>
struct reverse_adapter { struct reverse_adapter {
T& iterable; T& iterable;
constexpr auto begin() { constexpr auto begin()
{
using namespace std; using namespace std;
return rbegin(iterable); return rbegin(iterable);
} }
constexpr auto end() { constexpr auto end()
{
using namespace std; using namespace std;
return rend(iterable); return rend(iterable);
} }
@ -27,7 +29,8 @@ struct reverse_adapter {
} // namespace detail } // namespace detail
template<typename T> template<typename T>
constexpr detail::reverse_adapter<T> reverse(T&& iterable) { constexpr detail::reverse_adapter<T> reverse(T&& iterable)
{
return detail::reverse_adapter<T>{iterable}; return detail::reverse_adapter<T>{iterable};
} }

View File

@ -14,7 +14,7 @@ struct contains;
template<template<class...> class LT, class... Ts, class T> template<template<class...> class LT, class... Ts, class T>
struct contains<LT<Ts...>, T> struct contains<LT<Ts...>, T>
: bool_value<(false || ... || std::is_same_v<Ts, T>)> {}; : bool_value<(false || ... || std::is_same_v<Ts, T>)> {};
/// Does list L contain an element which is same as type T? /// Does list L contain an element which is same as type T?
template<class L, class T> template<class L, class T>

View File

@ -20,8 +20,10 @@ template<typename Function>
class scope_exit final { class scope_exit final {
public: public:
explicit scope_exit(Function&& fn) explicit scope_exit(Function&& fn)
: function(std::move(fn)) {} : function(std::move(fn)) {}
~scope_exit() noexcept {
~scope_exit() noexcept
{
function(); function();
} }
@ -33,8 +35,10 @@ template<typename Function>
class scope_fail final { class scope_fail final {
public: public:
explicit scope_fail(Function&& fn) explicit scope_fail(Function&& fn)
: function(std::move(fn)), exception_count(std::uncaught_exceptions()) {} : function(std::move(fn)), exception_count(std::uncaught_exceptions()) {}
~scope_fail() noexcept {
~scope_fail() noexcept
{
if (std::uncaught_exceptions() > exception_count) { if (std::uncaught_exceptions() > exception_count) {
function(); function();
} }
@ -49,8 +53,10 @@ template<typename Function>
class scope_success final { class scope_success final {
public: public:
explicit scope_success(Function&& fn) explicit scope_success(Function&& fn)
: function(std::move(fn)), exception_count(std::uncaught_exceptions()) {} : function(std::move(fn)), exception_count(std::uncaught_exceptions()) {}
~scope_success() {
~scope_success()
{
if (std::uncaught_exceptions() <= exception_count) { if (std::uncaught_exceptions() <= exception_count) {
function(); function();
} }
@ -64,17 +70,20 @@ private:
// We use ->* here as it has the highest precedence of the operators we can use. // We use ->* here as it has the highest precedence of the operators we can use.
template<typename Function> template<typename Function>
auto operator->*(scope_exit_tag, Function&& function) { auto operator->*(scope_exit_tag, Function&& function)
{
return scope_exit<std::decay_t<Function>>{std::forward<Function>(function)}; return scope_exit<std::decay_t<Function>>{std::forward<Function>(function)};
} }
template<typename Function> template<typename Function>
auto operator->*(scope_fail_tag, Function&& function) { auto operator->*(scope_fail_tag, Function&& function)
{
return scope_fail<std::decay_t<Function>>{std::forward<Function>(function)}; return scope_fail<std::decay_t<Function>>{std::forward<Function>(function)};
} }
template<typename Function> template<typename Function>
auto operator->*(scope_success_tag, Function&& function) { auto operator->*(scope_success_tag, Function&& function)
{
return scope_success<std::decay_t<Function>>{std::forward<Function>(function)}; return scope_success<std::decay_t<Function>>{std::forward<Function>(function)};
} }

View File

@ -11,7 +11,8 @@
namespace mcl::detail { namespace mcl::detail {
[[noreturn]] void assert_terminate_impl(fmt::string_view msg, fmt::format_args args) { [[noreturn]] void assert_terminate_impl(fmt::string_view msg, fmt::format_args args)
{
fmt::print(stderr, "assertion failed: "); fmt::print(stderr, "assertion failed: ");
fmt::vprint(stderr, msg, args); fmt::vprint(stderr, msg, args);
std::fflush(stderr); std::fflush(stderr);

View File

@ -9,7 +9,8 @@
#include <mcl/bit/bit_field.hpp> #include <mcl/bit/bit_field.hpp>
#include <mcl/stdint.hpp> #include <mcl/stdint.hpp>
TEST_CASE("mcl::bit::ones", "[bit]") { TEST_CASE("mcl::bit::ones", "[bit]")
{
const std::array cases{ const std::array cases{
std::make_tuple<size_t, u8>(0, 0x00), std::make_tuple<size_t, u8>(0, 0x00),
std::make_tuple<size_t, u8>(1, 0x01), std::make_tuple<size_t, u8>(1, 0x01),