16#include <unordered_map>
17#include <unordered_set>
32 template <
typename First,
typename Second>
33 using Pair = std::pair<First, Second>;
38 template <
typename... Args>
39 using Tuple = std::tuple<Args...>;
44 template <
typename T,
size_t Size>
45 using Array = std::array<T, Size>;
50 template <
size_t Size>
67 return {
reinterpret_cast<const char*
>(data.data()), data.size_bytes()};
74 requires std::is_trivially_copyable_v<T>
85 template <
typename T,
typename... Args>
88 T* data =
static_cast<T*
>(resource->
Allocate(size *
sizeof(T),
alignof(T)));
89 if constexpr (!std::is_trivially_constructible_v<T> ||
sizeof...(Args) > 0)
91 for (
size_t i = 0; i < size; i++)
92 std::construct_at(&data[i], std::forward<Args>(args)...);
100 template <
typename T>
103 if constexpr (!std::is_trivially_destructible_v<T>)
106 std::destroy_at(&item);
125 template <
typename... Args>
126 [[nodiscard]]
constexpr String Format(fmt::format_string<Args...> format, Args&&... args)
128 fmt::basic_memory_buffer<char, fmt::inline_buffer_size, StlDefaultAllocator<char>> buffer;
129 fmt::format_to(std::back_inserter(buffer), format, std::forward<Args>(args)...);
130 return String(buffer.data(), buffer.size());
148 template <
typename T>
149 using Vector = std::vector<T, StlAllocator<T>>;
157 template <
typename T,
typename Predicate = std::less<T>>
158 using Set = std::set<T, Predicate, StlAllocator<T>>;
167 template <
typename T,
typename Predicate = std::less<T>>
168 using MultiSet = std::multiset<T, Predicate, StlAllocator<T>>;
177 template <
typename K,
typename V,
typename Predicate = std::less<K>>
178 using Map = std::map<K, V, Predicate, StlAllocator<Pair<const K, V>>>;
185 template <
typename K,
typename V,
typename Hash = std::hash<K>,
typename KeyEq = std::equal_to<K>>
186 using HashMap = std::unordered_map<K, V, Hash, KeyEq, StlAllocator<Pair<const K, V>>>;
193 template <
typename K,
typename Hash = std::hash<K>,
typename KeyEq = std::equal_to<K>>
194 using HashSet = std::unordered_set<K, Hash, KeyEq, StlAllocator<K>>;
203 template <
typename K,
typename V,
typename Predicate = std::less<K>>
204 using MultiMap = std::multimap<K, V, Predicate, StlAllocator<Pair<const K, V>>>;
212 template <
typename T>
213 using Deque = std::deque<T, StlAllocator<T>>;
221 template <
typename T>
222 using Stack = std::stack<T, Deque<T>>;
230 template <
typename T>
231 using List = std::list<T, StlAllocator<T>>;
239 template <
typename T,
typename Container = Deque<T>>
240 using Queue = std::queue<T, Container>;
248 template <
typename T,
typename Predicate = std::less<T>,
typename Container = Vector<T>>
254 template <
typename T>
270 Base::operator=(std::nullopt);
276 Base::operator=(value);
282 Base::operator=(std::move(value));
295 const T* ptr =
GetIf();
300 T*
GetIf() {
return Base::has_value() ? std::addressof(Base::value()) :
nullptr; }
302 const T*
GetIf()
const {
return Base::has_value() ? std::addressof(Base::value()) :
nullptr; }
305 template <
typename... T>
306 struct Visitor : T...
308 using T::operator()...;
310 template <
typename... T>
311 struct VisitorDefault : T...
313 using T::operator()...;
314 template <
typename Arg>
315 requires(!std::is_invocable_v<T, Arg&> && ...)
316 auto operator()(Arg&) { };
323 template <
typename... Args>
326 using Base = std::variant<Args...>;
329 using Base::operator=;
332 template <
typename R, std::
size_t I = 0,
typename Vis,
typename Var>
335 if constexpr (I >=
sizeof...(Args))
337 CHECK_MSG(
false,
"valueless variant access");
342 if (var.index() == I)
344 auto* p = std::get_if<I>(&var);
345 CHECK_MSG(p,
"variant index/get_if mismatch");
347 if constexpr (std::is_void_v<R>)
349 std::invoke(vis, *p);
354 return std::invoke(vis, *p);
358 return VisitImpl<R, I + 1>(vis, var);
363 template <
typename... Visitors>
364 auto Visit(Visitors&&... visitors)
noexcept
366 using Vis = Visitor<std::decay_t<Visitors>...>;
368 static_assert((std::is_invocable_v<Vis&, Args&> && ...),
"Visitor must handle every variant alternative");
370 using R = std::invoke_result_t<Vis&, std::variant_alternative_t<0, Base>&>;
372 static_assert((std::same_as<R, std::invoke_result_t<Vis&, Args&>> && ...),
373 "All visitor overloads must return the same type");
375 Vis vis{std::forward<Visitors>(visitors)...};
378 return VisitImpl<R>(vis, base);
381 template <
typename... Visitors>
382 auto Visit(Visitors&&... visitors)
const noexcept
384 using Vis = Visitor<std::decay_t<Visitors>...>;
385 using ConstBase =
const Base;
387 static_assert((std::is_invocable_v<Vis&, const Args&> && ...),
388 "Visitor must handle every variant alternative");
391 using R = std::invoke_result_t<Vis&, std::variant_alternative_t<0, ConstBase>&>;
393 static_assert((std::same_as<R, std::invoke_result_t<Vis&, const Args&>> && ...),
394 "All visitor overloads must return the same type");
396 Vis vis{std::forward<Visitors>(visitors)...};
397 const Base& base = *
this;
399 return VisitImpl<R>(vis, base);
402 template <
typename... Visitors>
405 using Vis = VisitorDefault<std::decay_t<Visitors>...>;
407 static_assert((std::is_invocable_v<Vis&, Args&> && ...),
"Visitor must handle every variant alternative");
409 using R = std::invoke_result_t<Vis&, std::variant_alternative_t<0, Base>&>;
411 static_assert((std::same_as<R, std::invoke_result_t<Vis&, Args&>> && ...),
412 "All visitor overloads must return the same type");
414 Vis vis{std::forward<Visitors>(visitors)...};
417 return VisitImpl<R>(vis, base);
420 template <
typename... Visitors>
423 using Vis = VisitorDefault<std::decay_t<Visitors>...>;
424 using ConstBase =
const Base;
426 static_assert((std::is_invocable_v<Vis&, const Args&> && ...),
427 "Visitor must handle every variant alternative");
429 static_assert((std::is_nothrow_invocable_v<Vis&, const Args&> && ...),
430 "Visitor must be noexcept for every variant alternative");
432 using R = std::invoke_result_t<Vis&, std::variant_alternative_t<0, ConstBase>&>;
434 static_assert((std::same_as<R, std::invoke_result_t<Vis&, const Args&>> && ...),
435 "All visitor overloads must return the same type");
437 Vis vis{std::forward<Visitors>(visitors)...};
438 const Base& base = *
this;
440 return VisitImpl<R>(vis, base);
443 template <
typename T>
446 CHECK_MSG(GetIf<T>(),
"null-variant access");
452 template <
typename T>
453 [[nodiscard]]
constexpr const T&
Get()
const
455 CHECK_MSG(GetIf<T>(),
"null-variant access");
461 template <
typename T>
464 return std::get_if<T>(
this);
469 template <
typename T>
470 [[nodiscard]]
constexpr const T*
GetIf()
const
472 return std::get_if<T>(
this);
480 using namespace std::ranges;
484 template <
typename Range>
491 return std::ranges::find(
range, value) != std::ranges::end(
range);
497 template <
typename T>
500 if (
auto it = std::ranges::begin(range); it != std::ranges::end(range))
508 template <
typename T>
513 template <
typename T>
514 [[nodiscard]]
constexpr uint64_t
FNV1a64(Span<T> span)
noexcept
#define CHECK_MSG(expr, format_str,...)
Allocator interface (noexcept)
Definition Allocator.hpp:29
virtual void Deallocate(pointer ptr) noexcept=0
virtual pointer Allocate(size_type size, size_t alignment=alignof(std::max_align_t)) noexcept=0
constexpr Optional< range_value_t< T > > FirstOf(T &&range)
Returns the first element of a range, or an empty Optional if the range is empty.
Definition Container.hpp:498
Lock-free atomic primitives and implementations of data structures.
Definition Allocator.hpp:6
std::vector< T, StlAllocator< T > > Vector
std::vector with explicit Foundation::Core::StlAllocator constructor
Definition Container.hpp:149
std::tuple< Args... > Tuple
Alias for std::tuple
Definition Container.hpp:39
std::multimap< K, V, Predicate, StlAllocator< Pair< const K, V > > > MultiMap
std::multimap with explicit Foundation::Core::StlAllocator constructor
Definition Container.hpp:204
uint64_t FNV1a64CombineBytes(uint64_t hash, void const *data, size_t size) noexcept
Definition Hash.hpp:18
std::queue< T, Container > Queue
std::queue with explicit Foundation::Core::StlAllocator constructor
Definition Container.hpp:240
std::basic_string< char, std::char_traits< char >, StlAllocator< char > > StringAlloc
std::basic_string<char> with explicit Foundation::Core::StlAllocator constructor
Definition Container.hpp:139
void DestructSpan(Allocator *resource, Span< T > span)
Convenience function for destructing a Span allocated with ConstructSpan. Calls destructors in-place ...
Definition Container.hpp:101
Span< T > ConstructSpan(Allocator *resource, size_t size, Args &&... args)
Convenience function for constructing a Span with memory allocated from a Foundation::Core::Allocator...
Definition Container.hpp:86
std::pair< First, Second > Pair
Alias for std::pair
Definition Container.hpp:33
constexpr String Format(fmt::format_string< Args... > format, Args &&... args)
String wrapper for Format().
Definition Container.hpp:126
std::unordered_set< K, Hash, KeyEq, StlAllocator< K > > HashSet
std::unordered_set with explicit Foundation::Core::StlAllocator constructor.
Definition Container.hpp:194
constexpr uint64_t FNV1a64(Span< const T > span) noexcept
Definition Container.hpp:509
std::set< T, Predicate, StlAllocator< T > > Set
std::set with explicit Foundation::Core::StlAllocator constructor
Definition Container.hpp:158
std::unordered_map< K, V, Hash, KeyEq, StlAllocator< Pair< const K, V > > > HashMap
std::unordered_map with explicit Foundation::Core::StlAllocator constructor.
Definition Container.hpp:186
std::map< K, V, Predicate, StlAllocator< Pair< const K, V > > > Map
std::map with explicit Foundation::Core::StlAllocator constructor
Definition Container.hpp:178
std::list< T, StlAllocator< T > > List
std::list with explicit Foundation::Core::StlAllocator constructor
Definition Container.hpp:231
std::bitset< Size > Bitset
Alias for std::bitset
Definition Container.hpp:51
Span< const T > AsSpan(T const &data)
Helper to construct one const r-value as a single element span.
Definition Container.hpp:73
std::basic_string< char, std::char_traits< char >, StlDefaultAllocator< char > > String
Alias for std::basic_string<char>, without an explicit allocator constructor.
Definition Container.hpp:120
std::priority_queue< T, Container, Predicate > PriorityQueue
std::priority_queue with explicit Foundation::Core::StlAllocator constructor
Definition Container.hpp:249
constexpr uint64_t kFNV1a64OffsetBasis
Definition Hash.hpp:10
std::stack< T, Deque< T > > Stack
std::stack with explicit Foundation::Core::StlAllocator constructor
Definition Container.hpp:222
std::multiset< T, Predicate, StlAllocator< T > > MultiSet
std::multiset with explicit Foundation::Core::StlAllocator constructor
Definition Container.hpp:168
std::array< T, Size > Array
Alias for std::array
Definition Container.hpp:45
std::basic_string_view< char > StringView
Alias for std::basic_string_view<char>
Definition Container.hpp:56
Span< const char > AsBytes(Span< T > data)
Definition Container.hpp:65
std::span< T > Span
Alias for std::span
Definition Container.hpp:62
std::deque< T, StlAllocator< T > > Deque
std::deque with explicit Foundation::Core::StlAllocator constructor
Definition Container.hpp:213
std::optional with convenience Get()/GetIf() methods.
Definition Container.hpp:256
const T & Get() const
Definition Container.hpp:293
T * GetIf()
Definition Container.hpp:300
Optional & operator=(Optional &&)=default
Optional & operator=(const T &value)
Definition Container.hpp:274
std::optional< T > Base
Definition Container.hpp:257
Optional(Optional &&)=default
const T * GetIf() const
Definition Container.hpp:302
Optional & operator=(const Optional &)=default
Optional(const Optional &)=default
Optional & operator=(T &&value)
Definition Container.hpp:280
Optional & operator=(std::nullopt_t) noexcept
Definition Container.hpp:268
T & Get()
Definition Container.hpp:286
Range predicate that checks if a value is contained within a given range.
Definition Container.hpp:486
constexpr bool operator()(auto &&value) const
Definition Container.hpp:489
ContainedBy(Range const &range)
Definition Container.hpp:488
Range const & range
Definition Container.hpp:487
std::allocator adaptor for Foundation::Core::Allocator
Definition Allocator.hpp:87
Definition Allocator.hpp:246
std::variant with C++23 visit() behavior and convenience Get()/GetIf() methods. Also read upon https:...
Definition Container.hpp:325
constexpr T * GetIf()
Definition Container.hpp:462
auto Visit(Visitors &&... visitors) const noexcept
Definition Container.hpp:382
auto VisitDefault(Visitors &&... visitors) const noexcept
Definition Container.hpp:421
auto Visit(Visitors &&... visitors) noexcept
Definition Container.hpp:364
std::variant< Args... > Base
Definition Container.hpp:326
constexpr const T & Get() const
Definition Container.hpp:453
constexpr const T * GetIf() const
Definition Container.hpp:470
auto VisitDefault(Visitors &&... visitors) noexcept
Definition Container.hpp:403
static R VisitImpl(Vis &vis, Var &var) noexcept
Definition Container.hpp:333
constexpr T & Get()
Definition Container.hpp:444