summaryrefslogtreecommitdiff
path: root/AK/StdLibExtras.h
AgeCommit message (Collapse)Author
2021-09-04AK: Make declaration of std::move and std::forward optionalStephan Unverwerth
This introduces a new define AK_DONT_REPLACE_STD that disables our own implementation of std::move and std::forward. Some ports include both STL and AK headers which causes conflicts when trying to resolve those functions. The port can define AK_DONT_REPLACE_STD before including Serenity headers in that case.
2021-09-01AK: Move forward() into the std namespaceAndreas Kling
Same as we already did with move(). This allows compiler diagnostics and static analyzers like SonarCloud to detect more issues.
2021-08-30AK: Return early from swap() when swapping the same objectTimothy Flynn
When swapping the same object, we could end up with a double-free error. This was found while quick-sorting a Vector of Variants holding complex types, reproduced by the new swap_same_complex_object test case.
2021-07-15AK: Add workaround for clang-format 12 problems with conceptsDaniel Bertalan
2021-07-08AK+Userland: Add generic `AK::abs()` function and use itDaniel Bertalan
Previously, in LibGFX's `Point` class, calculated distances were passed to the integer `abs` function, even if the stored type was a float. This caused the value to unexpectedly be truncated. Luckily, this API was not used with floating point types, but that can change in the future, so why not fix it now :^) Since we are in C++, we can use function overloading to make things easy, and to automatically use the right version. This is even better than the LibC/LibM functions, as using a bit of hackery, they are able to be constant-evaluated. They use compiler intrinsics, so they do not depend on external code and the compiler can emit the most optimized code by default. Since we aren't using the C++ standard library's trick of importing everything into the `AK` namespace, this `abs` function cannot be exported to the global namespace, as the names would clash.
2021-06-27AK: Make the constexpr StringView methods actually constexprAli Mohammad Pur
Also add some tests to ensure that they _remain_ constexpr. In general, any runtime assertions, weirdo C casts, pointer aliasing, and such shenanigans should be gated behind the (helpfully newly added) AK::is_constant_evaluated() function when the intention is to write constexpr-capable code. a.k.a. deliver promises of constexpr-ness :P
2021-06-23AK: Make {min,max,clamp}(T, U) work when U can be implicitly cast to TAli Mohammad Pur
It was really annoying to `static_cast` the arguments to be the same type, so instead of doing that, just convert the second one to the first one, and let the compiler warn about sign differences and truncation.
2021-06-15AK: Add a function that casts an enum to its underlying typeAli Mohammad Pur
This is basically the same thing as `std::to_underlying(Enum)`.
2021-06-06AK+Everywhere: Disallow constructing Functions from incompatible typesAli Mohammad Pur
Previously, AK::Function would accept _any_ callable type, and try to call it when called, first with the given set of arguments, then with zero arguments, and if all of those failed, it would simply not call the function and **return a value-constructed Out type**. This lead to many, many, many hard to debug situations when someone forgot a `const` in their lambda argument types, and many cases of people taking zero arguments in their lambdas to ignore them. This commit reworks the Function interface to not include any such surprising behaviour, if your function instance is not callable with the declared argument set of the Function, it can simply not be assigned to that Function instance, end of story.
2021-05-29AK: Extend round_to_power_of_two to types other than `unsigned`Andrew Kaster
The previous implementation hardcoded unsigned, when the same logic easily extends to unsigned long, signed types, and other Integral types.
2021-04-22Everything: Move to SPDX license identifiers in all files.Brian Gianforcaro
SPDX License Identifiers are a more compact / standardized way of representing file license information. See: https://spdx.dev/resources/use/#identifiers This was done with the `ambr` search and replace tool. ambr --no-parent-ignore --key-from-file --rep-from-file key.txt rep.txt *
2021-04-16AK+Kernel: Make IntrusiveList capable of holding non-raw pointersAnotherTest
This should allow creating intrusive lists that have smart pointers, while remaining free (compared to the impl before this commit) when holding raw pointers :^) As a sidenote, this also adds a `RawPtr<T>` type, which is just equivalent to `T*`. Note that this does not actually use such functionality, but is only expected to pave the way for #6369, to replace NonnullRefPtrVector<T> with intrusive lists. As it is with zero-cost things, this makes the interface a bit less nice by requiring the type name of what an `IntrusiveListNode` holds (and optionally its container, if not RawPtr), and also requiring the type of the container (normally `RawPtr`) on the `IntrusiveList` instance.
2021-04-10AK+Everywhere: Make StdLibExtras templates less wrapper-yAnotherTest
This commit makes the user-facing StdLibExtras templates and utilities arguably more nice-looking by removing the need to reach into the wrapper structs generated by them to get the value/type needed. The C++ standard library had to invent `_v` and `_t` variants (likely because of backwards compat), but we don't need to cater to any codebase except our own, so might as well have good things for free. :^)
2021-03-28AK: Add IsSigned conterpart to IsUnsigned.Michel Hermier
2021-03-28AK: Make Concepts.h and StdLibExtras.h properly alias their own sumbols.Michel Hermier
2021-03-17AK: Move move() into the "std" namespaceAndreas Kling
This makes GCC emit warnings about redundant and pessimizing moves. It also allows static analyzers like clang-tidy to detect common bugs like use-after-move.
2021-03-09AK: Include Assertions.h in StdLibExtras.hMițca Dumitru
2021-03-05AK: Implement IsEnum<T> and UnderlyingType<T> type traitsBrian Gianforcaro
I needed these meta-programming type traits while working on something else. Add basic support for these two type traits as well as some tests.
2021-02-23Everywhere: Rename ASSERT => VERIFYAndreas Kling
(...and ASSERT_NOT_REACHED => VERIFY_NOT_REACHED) Since all of these checks are done in release builds as well, let's rename them to VERIFY to prevent confusion, as everyone is used to assertions being compiled out in release. We can introduce a new ASSERT macro that is specifically for debug checks, but I'm doing this wholesale conversion first since we've accumulated thousands of these already, and it's not immediately obvious which ones are suitable for ASSERT.
2021-02-23AK+Userland: Extend the compiletime format string check to other functionsAnotherTest
Thanks to @trflynn89 for the neat implicit consteval ctor trick! This allows us to basically slap `CheckedFormatString` on any formatting function, and have its format argument checked at compiletime. Note that there is a validator bug where it doesn't parse inner replaced fields like `{:~>{}}` correctly (what should be 'left align with next argument as size' is parsed as `{:~>{` following a literal closing brace), so the compiletime checks are disabled on these temporarily by forcing them to be StringViews. This commit also removes the now unused `AK::StringLiteral` type (which was introduced for use with NTTP strings).
2021-02-10AK: Make IsUnsigned<T> behave as you would expectAndreas Kling
2021-02-08AK: Add dbgln() format checkingAnotherTest
This checks the following things: - No unclosed braces in format string `dbgln("a:{}}", a)` where the '}}' would be interpreted as a literal '}' `dbgln("a:{", a)` where someone with a faulty keyboard like mine could generate - No extra closed braces in format string `dbgln("a:{{}", a)` where the '{{' would interpreted as a literal '{' `dbgln("a:}", a)` where someone with a faulty keyboard could generate - No references to nonexistent arguments `dbgln("a:{} b:{}", a)` where the value of `b` is not in the arguments list - No unconsumed argument `dbgln("a:{1}", not_used, 1)` where `not_used` is extraneous
2021-01-28Lagom+AK: Remove remains of clang -Wconsumed usageAndreas Kling
We stopped using that warning ages ago since it confused the compiler.
2020-12-30AK: Add tests for type traits and IndexSequenceAndrew Kaster
Use TypeLists to add test for IsIntegral, IsFloatingPoint, IsVoid, IsNullPointer, IsArithmetic, IsFundamental, and AddConst type traits. More can "easily" be added once the TypeList and macro magic is squinted at for long enough :).
2020-12-30AK: Add a TypeList class for expanded compile-time toolsAndrew Kaster
Also add IndexSequence and associated helpers. The TypeList class can be queried for what type is at a certain index, and there are two helper functions: for_each_type, and for_each_type_zipped. for_each_type will invoke a lambda with a TypeWrapper object for each type in the type list. The original type can be obtained by extracting the ::Type from the type of your generic lambda's one argument. for_each_type_zipped will walk two TypeLists in lockstep and pass a TypeWrapper object for the current index in each list to a generic lambda. The original type from the TypeList can again be extracted via the ::Type of the generic lambda's two parameters.
2020-12-30AK: Add IsArithmetic and IsFundamental type traitsAndrew Kaster
Also, make sure to using AK::IsNullPointer
2020-12-29AK+Format: Accept unsigned long in replacement fields.asynts
I ran into this exact but at least twenty times in Serenity alone. The C++ Standard dictates that 'unsigned long' and 'unsigned long long' are distinct types even though on most platforms they are usually both 64 bit integers. Also it wasn't possible to evaluate IsIntegral<T> for types that were not integers since it used MakeUnsigned<T> internally.
2020-12-26AK: Make AK::IsSame<T, U>::value a constexpr boolAnotherTest
It being an enum value was preventing it from being used without `!!` in requires clauses (bool also makes more sense anyway).
2020-12-21Everywhere: Switch from (void) to [[maybe_unused]] (#4473)Lenny Maiorani
Problem: - `(void)` simply casts the expression to void. This is understood to indicate that it is ignored, but this is really a compiler trick to get the compiler to not generate a warning. Solution: - Use the `[[maybe_unused]]` attribute to indicate the value is unused. Note: - Functions taking a `(void)` argument list have also been changed to `()` because this is not needed and shows up in the same grep command.
2020-11-12AK: Prefer using instead of typedefLenny Maiorani
Problem: - `typedef` is a keyword which comes from C and carries with it old syntax that is hard to read. - Creating type aliases with the `using` keyword allows for easier future maintenance because it supports template syntax. - There is inconsistent use of `typedef` vs `using`. Solution: - Use `clang-tidy`'s checker called `modernize-use-using` to update the syntax to use the newer syntax. - Remove unused functions to make `clang-tidy` happy. - This results in consistency within the codebase.
2020-11-10AK: Make RefPtr, NonnullRefPtr, WeakPtr thread safeTom
This makes most operations thread safe, especially so that they can safely be used in the Kernel. This includes obtaining a strong reference from a weak reference, which now requires an explicit call to WeakPtr::strong_ref(). Another major change is that Weakable::make_weak_ref() may require the explicit target type. Previously we used reinterpret_cast in WeakPtr, assuming that it can be properly converted. But WeakPtr does not necessarily have the knowledge to be able to do this. Instead, we now ask the class itself to deliver a WeakPtr to the type that we want. Also, WeakLink is no longer specific to a target type. The reason for this is that we want to be able to safely convert e.g. WeakPtr<T> to WeakPtr<U>, and before this we just reinterpret_cast the internal WeakLink<T> to WeakLink<U>, which is a bold assumption that it would actually produce the correct code. Instead, WeakLink now operates on just a raw pointer and we only make those constructors/operators available if we can verify that it can be safely cast. In order to guarantee thread safety, we now use the least significant bit in the pointer for locking purposes. This also means that only properly aligned pointers can be used.
2020-11-10AK: Add RefPtrTraits to allow implementing custom null pointersTom
This adds the ability to implement custom null states that allow storing state in null pointers.
2020-10-20Everywhere: Redundant inline specifier on constexpr functions (#3807)Lenny Maiorani
Problem: - `constexpr` functions are decorated with the `inline` specifier keyword. This is redundant because `constexpr` functions are implicitly `inline`. - [dcl.constexpr], §7.1.5/2 in the C++11 standard): "constexpr functions and constexpr constructors are implicitly inline (7.1.2)". Solution: - Remove the redundant `inline` keyword.
2020-10-20Checked: constexpr supportLenny Maiorani
Problem: - `Checked` is not `constexpr`-aware. Solution: - Decorate member functions with `constexpr` keyword. - Add tests to ensure the functionality where possible.
2020-10-04LibIPC: Make IPC::encode() and ::decode() fail at compiletime when usedAnotherTest
This would previously fail at runtime, and it would have zero indication of what exactly went wrong. Also adds `AK::DependentFalse<Ts...>', which is a...dependent false.
2020-10-02AK: Add is_trivial and is_trivially_copyableTom
2020-09-22AK: Consider long and unsigned long as integral types.asynts
Two things I hate about C++: 1. 'int', 'signed int' and 'unsigned int' are two distinct types while 'char, 'signed char' and 'unsigned char' are *three* distinct types. This is because 'signed int' is an alias for 'int' but 'signed char' can't be an alias for 'char' because on some weird systems 'char' is unsigned. One might think why not do it the other way around, make 'int' an alias for 'signed int' and 'char' an alias for whatever that is on the platform, or make 'char' signed on all platforms. But who am I to ask? 2. 'unsigned long' and 'unsigned long long' are always different types, even if both are 64 bit numbers. This commit fixes a few bugs that coming from this. See Also: 1b3169f405ac9250b65ee3608e2962f51d2d8e3c.
2020-09-11AK: Generalise 'PrintfImplementation'AnotherTest
This makes PrintfImplementation usable with any sequence, provided that a 'next element' function can be written for it. Does not affect the behaviour of printf() and co.
2020-08-27AK: Define MakeUnsigned and MakeSigned for char.asynts
For some weird reason the C++ standard considers char, signed char and unsigned char *three* different types. On the other hand int is just an alias for signed int, meaning that int, signed int and unsigned int are just *two* different types. https://stackoverflow.com/a/32856568/8746648
2020-08-23AK: Print RHS and LHS in EXPECT_EQ if we canBen Wiederhake
This makes error messages more useful during debugging. Old: START Running test compare_views FAIL: ../AK/Tests/TestStringView.cpp:59: EXPECT_EQ(view1, "foobar") failed New: START Running test compare_views FAIL: ../AK/Tests/TestStringView.cpp:59: EXPECT_EQ(view1, "foobar") failed: LHS="foo", RHS="foobar"
2020-08-16AK: HashTable add a constructor that allows preallocation of capacity + Use ↵Muhammad Zahalqa
in CppLexer. (#3147) 1. Add general utility to get array number of elements. 2. Add Needed API to AK::HashTable 3. Refactor CppLexer initialization
2020-08-06AK: Add Integral and FloatingPoint concepts.asynts
2020-08-06AK: Rename MakeUnsigned::type to MakeUnsigned::Type.asynts
Also renames MakeSigned::type to MakeSigned::Type.
2020-08-06AK: Make min/max behave like the STL for equivalent inputs (#2976)Muhammad Zahalqa
min(a, b) now returns a if both are equivalent. max(a, b) now returns a if both are equivalent.
2020-07-26AK: Add global is<T>() and downcast<T>()Andreas Kling
Let's unify the is<T>/to<T> implementations that currently exist in separate versions in LibCore and LibWeb.
2020-07-24AK: Add a couple more helper templates to StdLibExtrasAndreas Kling
2020-07-18AK: Use "signed char" as the opposite of "unsigned char"Andreas Kling
I totally forgot about the C++ basics here. There are three distinct types: "char", "signed char" and "unsigned char". Whether "char" is signed or unsigned is implementation specific.
2020-05-23AK: Add MakeSigned<T> helper templateAndreas Kling
2020-04-22AK: Tweak exchange() implementationAndreas Kling
Make it constexpr and do perfect forwarding.
2020-04-15AK: Add MakeUnsigned<T> helper templateAndreas Kling