Allocator Builder
Policy Based C++ Template Allocator Library
 All Classes Functions Variables Enumerations Enumerator Groups Pages
traits.hpp
1 //
3 // Copyright 2014 Felix Petriconi
4 //
5 // License: http://boost.org/LICENSE_1_0.txt, Boost License 1.0
6 //
7 // Authors: http://petriconi.net, Felix Petriconi
8 //
10 #pragma once
11 
12 #include <type_traits>
13 #include <stddef.h>
14 
15 namespace alb {
16 
17  inline namespace v_100 {
18  struct block;
19 
20  namespace traits {
26  template <typename T> struct has_expand
27  {
28  template <typename U, bool (U::*)(block &, size_t) noexcept> struct Check;
29  template <typename U> static constexpr bool test(Check<U, &U::expand> *) { return true; }
30  template <typename U> static constexpr bool test(...) { return false; }
31 
32  static constexpr bool value = test<T>(nullptr);
33  };
34 
40  template <typename T> struct has_deallocate_all
41  {
42  template <typename U, void (U::*)()noexcept> struct Check;
43  template <typename U> static bool test(Check<U, &U::deallocate_all> *) { return true; }
44  template <typename U> static bool test(...) { return false; }
45 
46  static constexpr bool value = test<T>(nullptr);
47  };
48 
54  template <typename T> struct has_owns
55  {
56  template <typename U, bool (U::*)(const block &) const noexcept> struct Check;
57  template <typename U> static constexpr bool test(Check<U, &U::owns> *) { return true; }
58  template <typename U> static constexpr bool test(...) { return false; }
59 
60  static constexpr bool value = test<T>(nullptr);
61  };
62 
75  template <class T1, class T2> struct both_same_base : std::false_type {
76  };
77 
78  template <class T1> struct both_same_base<T1, T1> : std::true_type {
79  };
80 
81  template <template <size_t> class Allocator, size_t P1, size_t P2>
82  struct both_same_base<Allocator<P1>, Allocator<P2>> : std::true_type {
83  };
84 
85  template <template <size_t, size_t> class Allocator, size_t P1, size_t P2, size_t P3, size_t P4>
86  struct both_same_base<Allocator<P1, P2>, Allocator<P3, P4>> : std::true_type {
87  };
88 
89  template <template <size_t, size_t, size_t> class Allocator, size_t P1, size_t P2, size_t P3,
90  size_t P4, size_t P5, size_t P6>
91  struct both_same_base<Allocator<P1, P2, P3>, Allocator<P4, P5, P6>> : std::true_type {
92  };
93 
94  template <template <size_t, size_t, size_t, size_t> class Allocator, size_t P1, size_t P2,
95  size_t P3, size_t P4, size_t P5, size_t P6, size_t P7, size_t P8>
96  struct both_same_base<Allocator<P1, P2, P3, P4>, Allocator<P5, P6, P7, P8>> : std::true_type {
97  };
98 
99  template <template <class> class Allocator, class A1, class A2>
100  struct both_same_base<Allocator<A1>, Allocator<A2>> : std::true_type {
101  };
102 
103  template <template <class, size_t> class Allocator, class A1, size_t P1, class A2, size_t P2>
104  struct both_same_base<Allocator<A1, P1>, Allocator<A2, P2>> : std::true_type {
105  };
106 
107  template <template <class, size_t, size_t> class Allocator, class A1, size_t P1, size_t P2,
108  class A2, size_t P3, size_t P4>
109  struct both_same_base<Allocator<A1, P1, P2>, Allocator<A2, P3, P4>> : std::true_type {
110  };
111 
112  template <template <class, size_t, size_t, size_t> class Allocator, class A1, size_t P1,
113  size_t P2, size_t P3, class A2, size_t P4, size_t P5, size_t P6>
114  struct both_same_base<Allocator<A1, P1, P2, P3>, Allocator<A2, P4, P5, P6>> : std::true_type {
115  };
116 
117  template <template <class, size_t, size_t, size_t, size_t> class Allocator, class A1, size_t P1,
118  size_t P2, size_t P3, size_t P4, class A2, size_t P5, size_t P6, size_t P7, size_t P8>
119  struct both_same_base<Allocator<A1, P1, P2, P3, P4>, Allocator<A2, P5, P6, P7, P8>>
120  : std::true_type {
121  };
122 
129  template <class Allocator, typename Enabled = void> struct Expander;
130 
131  template <class Allocator>
132  struct Expander<Allocator, typename std::enable_if<has_expand<Allocator>::value>::type> {
133  static bool do_it(Allocator &a, block &b, size_t delta) noexcept
134  {
135  return a.expand(b, delta);
136  }
137  };
138 
139  template <class Allocator>
140  struct Expander<Allocator, typename std::enable_if<!has_expand<Allocator>::value>::type> {
141  static bool do_it(Allocator &, block &, size_t) noexcept
142  {
143  return false;
144  }
145  };
146 
153  template <class Allocator, typename Enabled = void> struct AllDeallocator;
154 
155  template <class Allocator>
156  struct AllDeallocator<Allocator,
157  typename std::enable_if<has_deallocate_all<Allocator>::value>::type> {
158  static void do_it(Allocator &a) noexcept
159  {
160  a.deallocate_all();
161  }
162  };
163 
164  template <class Allocator>
165  struct AllDeallocator<Allocator,
166  typename std::enable_if<!has_deallocate_all<Allocator>::value>::type> {
167  static void do_it(Allocator &) noexcept
168  {
169  }
170  };
171 
180  template <class A, class B, bool> struct type_switch;
181 
182  template <class A, class B> struct type_switch<A, B, true> {
183  using type = A;
184  };
185 
186  template <class A, class B> struct type_switch<A, B, false> {
187  using type = B;
188  };
189  }
190  }
191 
192  using namespace v_100;
193 }