File: memory.hpp

package info (click to toggle)
higan 106-2
  • links: PTS, VCS
  • area: main
  • in suites: bullseye, buster
  • size: 9,640 kB
  • sloc: cpp: 108,736; ansic: 809; makefile: 22; sh: 7
file content (90 lines) | stat: -rw-r--r-- 2,109 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
#pragma once

namespace nall {

template<typename T> auto vector<T>::reset() -> void {
  if(!_pool) return;

  for(uint n : range(_size)) _pool[n].~T();
  memory::free(_pool - _left);

  _pool = nullptr;
  _size = 0;
  _left = 0;
  _right = 0;
}

template<typename T> auto vector<T>::release() -> T* {
  auto pool = _pool;
  _pool = nullptr;
  _size = 0;
  _left = 0;
  _right = 0;
  return pool;
}

template<typename T> auto vector<T>::reserveLeft(uint capacity) -> bool {
  if(_size + _left >= capacity) return false;

  uint left = bit::round(capacity);
  auto pool = (T*)memory::allocate(sizeof(T) * (left + _right)) + (left - _size);
  for(uint n : range(_size)) new(pool + n) T(move(_pool[n]));
  memory::free(_pool - _left);

  _pool = pool;
  _left = left - _size;

  return true;
}

template<typename T> auto vector<T>::reserveRight(uint capacity) -> bool {
  if(_size + _right >= capacity) return false;

  uint right = bit::round(capacity);
  auto pool = (T*)memory::allocate(sizeof(T) * (_left + right)) + _left;
  for(uint n : range(_size)) new(pool + n) T(move(_pool[n]));
  memory::free(_pool - _left);

  _pool = pool;
  _right = right - _size;

  return true;
}

template<typename T> auto vector<T>::resizeLeft(uint size, const T& value) -> bool {
  if(size < _size) {  //shrink
    for(uint n : range(_size - size)) _pool[n].~T();
    _pool += _size - size;
    _left += _size - size;
    _size = size;
    return true;
  }
  if(size > _size) {  //grow
    reserveLeft(size);
    _pool -= size - _size;
    for(uint n : rrange(size - _size)) new(_pool + n) T(value);
    _left -= size - _size;
    _size = size;
    return true;
  }
  return false;
}

template<typename T> auto vector<T>::resizeRight(uint size, const T& value) -> bool {
  if(size < _size) {  //shrink
    for(uint n : range(size, _size)) _pool[n].~T();
    _right += _size - size;
    _size = size;
    return true;
  }
  if(size > _size) {  //grow
    reserveRight(size);
    for(uint n : range(_size, size)) new(_pool + n) T(value);
    _right -= size - _size;
    _size = size;
    return true;
  }
  return false;
}

}