File: unique-pointer.hpp

package info (click to toggle)
ares 126-3
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 32,600 kB
  • sloc: cpp: 356,508; ansic: 20,394; makefile: 16; sh: 2
file content (116 lines) | stat: -rw-r--r-- 2,827 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#pragma once

namespace nall {

template<typename T>
struct unique_pointer {
  template<typename... P> static auto create(P&&... p) {
    return unique_pointer<T>{new T{forward<P>(p)...}};
  }

  using type = T;
  T* pointer = nullptr;
  function<void (T*)> deleter;

  unique_pointer(const unique_pointer&) = delete;
  auto operator=(const unique_pointer&) -> unique_pointer& = delete;

  unique_pointer(T* pointer = nullptr, const function<void (T*)>& deleter = {}) : pointer(pointer), deleter(deleter) {}
  ~unique_pointer() { reset(); }

  auto operator=(T* source) -> unique_pointer& {
    reset();
    pointer = source;
    return *this;
  }

  explicit operator bool() const { return pointer; }

  auto operator->() -> T* { return pointer; }
  auto operator->() const -> const T* { return pointer; }

  auto operator*() -> T& { return *pointer; }
  auto operator*() const -> const T& { return *pointer; }

  auto operator()() -> T& { return *pointer; }
  auto operator()() const -> const T& { return *pointer; }

  auto data() -> T* { return pointer; }
  auto data() const -> const T* { return pointer; }

  auto release() -> T* {
    auto result = pointer;
    pointer = nullptr;
    return result;
  }

  auto reset() -> void {
    if(pointer) {
      if(deleter) {
        deleter(pointer);
      } else {
        delete pointer;
      }
      pointer = nullptr;
    }
  }

  auto swap(unique_pointer<T>& target) -> void {
    std::swap(pointer, target.pointer);
    std::swap(deleter, target.deleter);
  }
};

template<typename T>
struct unique_pointer<T[]> {
  using type = T;
  T* pointer = nullptr;
  function<void (T*)> deleter;

  unique_pointer(const unique_pointer&) = delete;
  auto operator=(const unique_pointer&) -> unique_pointer& = delete;

  unique_pointer(T* pointer = nullptr, const function<void (T*)>& deleter = {}) : pointer(pointer), deleter(deleter) {}
  ~unique_pointer() { reset(); }

  auto operator=(T* source) -> unique_pointer& {
    reset();
    pointer = source;
    return *this;
  }

  explicit operator bool() const { return pointer; }

  auto operator()() -> T* { return pointer; }
  auto operator()() const -> T* { return pointer; }

  auto operator[](u64 offset) -> T& { return pointer[offset]; }
  auto operator[](u64 offset) const -> const T& { return pointer[offset]; }

  auto data() -> T* { return pointer; }
  auto data() const -> const T* { return pointer; }

  auto release() -> T* {
    auto result = pointer;
    pointer = nullptr;
    return result;
  }

  auto reset() -> void {
    if(pointer) {
      if(deleter) {
        deleter(pointer);
      } else {
        delete[] pointer;
      }
      pointer = nullptr;
    }
  }

  auto swap(unique_pointer<T[]>& target) -> void {
    std::swap(pointer, target.pointer);
    std::swap(deleter, target.deleter);
  }
};

}