STIR  6.3.0
mock-allocator.h
1 // Formatting library for C++ - mock allocator
2 //
3 // Copyright (c) 2012 - present, Victor Zverovich
4 // All rights reserved.
5 //
6 // For the license information refer to format.h.
7 
8 #ifndef FMT_MOCK_ALLOCATOR_H_
9 #define FMT_MOCK_ALLOCATOR_H_
10 
11 #include <assert.h> // assert
12 #include <stddef.h> // size_t
13 
14 #include <memory> // std::allocator_traits
15 
16 #include "gmock/gmock.h"
17 
18 template <typename T> class mock_allocator {
19  public:
20  using value_type = T;
21  using size_type = size_t;
22 
23  using pointer = T*;
24  using const_pointer = const T*;
25  using reference = T&;
26  using const_reference = const T&;
27  using difference_type = ptrdiff_t;
28 
29  template <typename U> struct rebind {
30  using other = mock_allocator<U>;
31  };
32 
33  mock_allocator() {}
34  mock_allocator(const mock_allocator&) {}
35 
36  MOCK_METHOD(T*, allocate, (size_t));
37  MOCK_METHOD(void, deallocate, (T*, size_t));
38 };
39 
40 template <typename Allocator, bool PropagateOnMove = true> class allocator_ref {
41  private:
42  Allocator* alloc_;
43 
44  void move(allocator_ref& other) {
45  alloc_ = other.alloc_;
46  other.alloc_ = nullptr;
47  }
48 
49  public:
50  using value_type = typename Allocator::value_type;
51  using propagate_on_container_move_assignment =
52  fmt::bool_constant<PropagateOnMove>;
53 
54  explicit allocator_ref(Allocator* alloc = nullptr) : alloc_(alloc) {}
55 
56  allocator_ref(const allocator_ref& other) : alloc_(other.alloc_) {}
57  allocator_ref(allocator_ref&& other) { move(other); }
58 
59  allocator_ref& operator=(allocator_ref&& other) {
60  assert(this != &other);
61  move(other);
62  return *this;
63  }
64 
65  allocator_ref& operator=(const allocator_ref& other) {
66  alloc_ = other.alloc_;
67  return *this;
68  }
69 
70  public:
71  auto get() const -> Allocator* { return alloc_; }
72 
73  auto allocate(size_t n) -> value_type* {
74  return std::allocator_traits<Allocator>::allocate(*alloc_, n);
75  }
76  void deallocate(value_type* p, size_t n) { alloc_->deallocate(p, n); }
77 
78  friend auto operator==(allocator_ref a, allocator_ref b) noexcept -> bool {
79  if (a.alloc_ == b.alloc_) return true;
80  return a.alloc_ && b.alloc_ && *a.alloc_ == *b.alloc_;
81  }
82 
83  friend auto operator!=(allocator_ref a, allocator_ref b) noexcept -> bool {
84  return !(a == b);
85  }
86 };
87 
88 #endif // FMT_MOCK_ALLOCATOR_H_