KTL
Loading...
Searching...
No Matches
threaded.h
Go to the documentation of this file.
1#pragma once
2
3#include "../utility/aligned_malloc.h"
4#include "../utility/alignment.h"
5#include "../utility/empty_base.h"
6#include "../utility/meta.h"
7#include "../utility/source_location.h"
8#include "threaded_fwd.h"
9
10#include <atomic>
11#include <memory>
12#include <mutex>
13#include <type_traits>
14
15namespace ktl
16{
17 template<typename Alloc>
19 {
20 private:
21 static_assert(detail::has_no_value_type_v<Alloc>, "Building on top of typed allocators is not allowed. Use allocators without a type");
22
23 public:
25
26 template<typename A = Alloc>
28 noexcept(std::is_nothrow_default_constructible_v<Alloc>) :
29 m_Alloc(),
30 m_Lock() {}
31
35 template<typename... Args,
36 typename = std::enable_if_t<
37 std::is_constructible_v<Alloc, Args...>>>
38 explicit threaded(Args&&... args)
39 noexcept(std::is_nothrow_constructible_v<Alloc, Args...>) :
40 m_Alloc(std::forward<Args>(args) ...),
41 m_Lock() {}
42
43 threaded(const threaded&) = delete;
44 threaded(threaded&&) = delete;
45
46 threaded& operator=(const threaded&) = delete;
48
49 bool operator==(const threaded& rhs) const
51 {
52 return m_Alloc == rhs.m_Alloc;
53 }
54
55 bool operator!=(const threaded& rhs) const
57 {
58 return m_Alloc != rhs.m_Alloc;
59 }
60
61#pragma region Allocation
62 void* allocate(size_t n, const source_location source = KTL_SOURCE())
63 noexcept(detail::has_nothrow_allocate_v<Alloc>)
64 {
65 try
66 {
67 std::lock_guard<std::mutex> lock(m_Lock);
68
69 return m_Alloc.allocate(n, source);
70 }
71 catch (const std::system_error&)
72 {
73 return nullptr;
74 }
75 }
76
77 void deallocate(void* p, size_t n)
79 {
80 try
81 {
82 std::lock_guard<std::mutex> lock(m_Lock);
83
84 m_Alloc.deallocate(p, n);
85 }
86 catch (const std::system_error&) {}
87 }
88#pragma endregion
89
90#pragma region Construction
91 template<typename T, typename... Args>
92 typename std::enable_if<detail::has_construct_v<Alloc, T*, Args...>, void>::type
93 construct(T* p, Args&&... args)
94 noexcept(detail::has_nothrow_construct_v<Alloc, T*, Args...>)
95 {
96 //std::lock_guard<std::mutex> lock(m_Lock); // Does it need to lock on construction?
97
98 m_Alloc.construct(p, std::forward<Args>(args)...);
99 }
100
101 template<typename T>
102 typename std::enable_if<detail::has_destroy_v<Alloc, T*>, void>::type
105 {
106 //std::lock_guard<std::mutex> lock(m_Lock);
107
108 m_Alloc.destroy(p);
109 }
110#pragma endregion
111
112#pragma region Utility
113 template<typename A = Alloc>
114 typename std::enable_if<detail::has_max_size_v<A>, size_type>::type
115 max_size() const
116 noexcept(detail::has_nothrow_max_size_v<A>)
117 {
118 return m_Alloc.max_size();
119 }
120
121 template<typename A = Alloc>
122 typename std::enable_if<detail::has_owns_v<A>, bool>::type
123 owns(void* p) const
125 {
126 return m_Alloc.owns(p);
127 }
128#pragma endregion
129
130 Alloc& get_allocator() noexcept
131 {
132 return m_Alloc;
133 }
134
135 const Alloc& get_allocator() const noexcept
136 {
137 return m_Alloc;
138 }
139
140 private:
141 KTL_EMPTY_BASE Alloc m_Alloc;
142 std::mutex m_Lock;
143 };
144}
Definition threaded.h:19
std::enable_if< detail::has_construct_v< Alloc, T *, Args... >, void >::type construct(T *p, Args &&... args) noexcept(detail::has_nothrow_construct_v< Alloc, T *, Args... >)
Definition threaded.h:93
bool operator!=(const threaded &rhs) const noexcept(detail::has_nothrow_not_equal_v< Alloc >)
Definition threaded.h:55
threaded(threaded &&)=delete
std::enable_if< detail::has_owns_v< A >, bool >::type owns(void *p) const noexcept(detail::has_nothrow_owns_v< A >)
Definition threaded.h:123
void * allocate(size_t n, const source_location source=KTL_SOURCE()) noexcept(detail::has_nothrow_allocate_v< Alloc >)
Definition threaded.h:62
bool operator==(const threaded &rhs) const noexcept(detail::has_nothrow_equal_v< Alloc >)
Definition threaded.h:49
std::enable_if< detail::has_max_size_v< A >, size_type >::type max_size() const noexcept(detail::has_nothrow_max_size_v< A >)
Definition threaded.h:115
Alloc & get_allocator() noexcept
Definition threaded.h:130
threaded(Args &&... args) noexcept(std::is_nothrow_constructible_v< Alloc, Args... >)
Constructor for forwarding any arguments to the underlying allocator.
Definition threaded.h:38
threaded & operator=(threaded &&)=delete
void deallocate(void *p, size_t n) noexcept(detail::has_nothrow_deallocate_v< Alloc >)
Definition threaded.h:77
const Alloc & get_allocator() const noexcept
Definition threaded.h:135
threaded & operator=(const threaded &)=delete
threaded() noexcept(std::is_nothrow_default_constructible_v< Alloc >)
Definition threaded.h:27
threaded(const threaded &)=delete
std::enable_if< detail::has_destroy_v< Alloc, T * >, void >::type destroy(T *p) noexcept(detail::has_nothrow_destroy_v< Alloc, T * >)
Definition threaded.h:103
detail::get_size_type_t< Alloc > size_type
Definition threaded.h:24
#define KTL_EMPTY_BASE
Definition empty_base.h:6
typename get_size_type< Alloc, void >::type get_size_type_t
Definition meta.h:33
constexpr bool has_nothrow_construct_v
Definition meta.h:123
constexpr bool has_construct_v
Definition meta.h:53
constexpr bool has_no_value_type_v
Definition meta.h:17
Definition cascading.h:16
#define KTL_SOURCE()
Definition source_location.h:11
Definition source_location.h:19