virtmem
virtual memory library for Arduino
vptr_utils.h
Go to the documentation of this file.
1 #ifndef VIRTMEM_VPTR_UTILS_H
2 #define VIRTMEM_VPTR_UTILS_H
3 
9 #include "config/config.h"
10 #include "vptr.h"
11 
12 #include <string.h>
13 
14 namespace virtmem {
15 
16 // Generic NULL type, partially based on https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/nullptr#Solution_and_Sample_Code
27 #ifndef VIRTMEM_CPP11
28 class NILL_t
29 {
30  void operator&() const; // prevent taking address
31 
32 public:
33  template <typename T> inline operator T*(void) const { return 0; }
34  template <typename C, typename M> inline operator M C::*(void) const { return 0; }
35  template <typename T, typename A> inline operator VPtr<T, A>(void) const { return VPtr<T, A>(); }
36  inline operator BaseVPtr(void) const { return BaseVPtr(); }
37  template <typename T, typename A> inline operator typename VPtr<T, A>::ValueWrapper(void) const { return VPtr<T, A>::ValueWrapper(0); }
38 };
39 #else
40 typedef nullptr_t NILL_t;
41 #endif
42 
43 extern const NILL_t NILL;
44 
76 template <typename TV> class VPtrLock
77 {
78  typedef typename TV::TPtr Ptr;
79 
80  TV virtPtr;
81  Ptr data;
82  VirtPageSize lockSize;
83  bool readOnly;
84 
85 public:
95  VPtrLock(const TV &v, VirtPageSize s, bool ro=false) :
96  virtPtr(v), lockSize(s), readOnly(ro) { lock(); }
103  VPtrLock(void) : data(0), lockSize(0), readOnly(false) { }
104  ~VPtrLock(void) { unlock(); }
105  VPtrLock(const VPtrLock &other) :
106  virtPtr(other.virtPtr), lockSize(other.lockSize),
107  readOnly(other.readOnly) { lock(); }
108 
114  void lock(void)
115  {
116 #ifdef VIRTMEM_WRAP_CPOINTERS
117  if (virtPtr.isWrapped())
118  data = virtPtr.unwrap();
119  else
120 #endif
121  data = static_cast<Ptr>(TV::getAlloc()->makeFittingLock(virtPtr.ptr, lockSize, readOnly));
122  }
123 
127  void lock(const TV &v, VirtPageSize s, bool ro=false)
128  {
129  virtPtr = v; lockSize = s; readOnly = ro;
130  lock();
131  }
132 
136  void unlock(void)
137  {
138 #ifdef VIRTMEM_WRAP_CPOINTERS
139  if (!virtPtr.isWrapped() && data)
140 #else
141  if (data)
142 #endif
143  {
144  TV::getAlloc()->releaseLock(virtPtr.ptr);
145  data = 0;
146  }
147  }
148 
149  Ptr operator *(void) { return data; }
150 
158  VirtPageSize getLockSize(void) const { return lockSize; }
159 };
160 
166 // Shortcut
175 template <typename T> VPtrLock<T> makeVirtPtrLock(const T &w, VirtPageSize s, bool ro=false)
176 { return VPtrLock<T>(w, s, ro); }
177 
178 namespace private_utils {
179 // Ugly hack from http://stackoverflow.com/a/12141673
180 // a null pointer of T is used to get the offset of m. The char & is to avoid any dereference operator overloads and the
181 // char * subtraction to get the actual offset.
182 template <typename C, typename M> ptrdiff_t getMembrOffset(const M C::*m)
183 { return ((char *)&((char &)((C *)(0)->*m)) - (char *)(0)); }
184 }
185 
196 template <typename C, typename M, typename A> inline VPtr<M, A> getMembrPtr(const VPtr<C, A> &c, const M C::*m)
197 { VPtr<M, A> ret; ret.setRawNum(c.getRawNum() + private_utils::getMembrOffset(m)); return ret; }
198 
212 template <typename C, typename M, typename NC, typename NM, typename A> inline VPtr<NM, A> getMembrPtr(const VPtr<C, A> &c, const M C::*m, const NM NC::*nm)
213 { VPtr<NM, A> ret = static_cast<VPtr<NM, A> >(static_cast<VPtr<char, A> >(getMembrPtr(c, m)) + private_utils::getMembrOffset(nm)); return ret; }
214 
215 }
216 
217 #include "vptr_utils.hpp"
218 
219 #endif // VIRTMEM_VPTR_UTILS_H
contains all code from virtmem
Definition: base_alloc.cpp:22
PtrNum getRawNum(void) const
Returns a numeric representation of this virtual pointer.
Definition: base_vptr.h:153
Ptr operator*(void)
Provides access to the data.
Definition: vptr_utils.h:149
VPtrLock(void)
Default constructor. No locks are created.
Definition: vptr_utils.h:103
void lock(void)
Recreates a virtual data lock after unlock was called.
Definition: vptr_utils.h:114
VPtrLock(const TV &v, VirtPageSize s, bool ro=false)
Constructs a virtual data lock class and creates a lock to the given data.
Definition: vptr_utils.h:95
This header file contains several variables that can be used to customize virtmem.
void setRawNum(PtrNum p)
Sets a virtual pointer from a numeric value.
Definition: base_vptr.h:159
uint16_t VirtPageSize
Numeric type used to store the size of a virtual memory page.
Definition: base_alloc.h:23
VPtr< M, A > getMembrPtr(const VPtr< C, A > &c, const M C::*m)
Obtains a virtual pointer to a data member that is stored in virtual memory.
Definition: vptr_utils.h:196
This header contains the class definition of the VPtr class.
VPtrLock(const VPtrLock &other)
Copy constructor, adds extra lock to data.
Definition: vptr_utils.h:105
VPtrLock< T > makeVirtPtrLock(const T &w, VirtPageSize s, bool ro=false)
Creates a virtual lock (shortcut)
Definition: vptr_utils.h:175
~VPtrLock(void)
Unlocks data if locked.
Definition: vptr_utils.h:104
const NILL_t NILL
Global instance of a NILL_t class.
Definition: utils.cpp:6
void lock(const TV &v, VirtPageSize s, bool ro=false)
Locks data. Parameters are described here.
Definition: vptr_utils.h:127
void unlock(void)
Unlocks data (if locked). Automatically called during destruction.
Definition: vptr_utils.h:136
Creates a lock to some virtual data.
Definition: vptr_utils.h:76
Generalized NULL pointer class.
Virtual pointer class that provides an interface to access virtual much like 'regular pointers'...
Definition: alloc.h:15
VirtPageSize getLockSize(void) const
Returns the actual size locked.
Definition: vptr_utils.h:158
This header file contains several overloads of common C functions that work with virtual pointers...