Pol  Revision:cb584c9
property.h
Go to the documentation of this file.
1 
7 #ifndef H_PROPERTY_ACCESSOR
8 #define H_PROPERTY_ACCESSOR
9 
10 #ifdef USE_SAFEINT
11 #include "../../lib/safeint/SafeInt.hpp"
12 #endif
13 
14 
15 /*
16  Constraints for Property class. Could be cleaner with some template
17  metaprogramming, but this works for now. Essentially, each struct has
18  a function apply<T>(x) which returns x in a valid range. To be used in
19  conjunction with Property<T, constraint = NoConstraint>.
20 
21 */
23 {
24  template <class T>
25  static T apply( const T x )
26  {
27  return x;
28  }
29 };
30 
31 template <int min>
32 struct MinValue
33 {
34  template <class T>
35  static T apply( const T x )
36  {
37  return ( x < min ) ? min : x;
38  }
39 };
40 
41 template <int max>
42 struct MaxValue
43 {
44  template <class T>
45  static T apply( const T x )
46  {
47  return ( x > max ) ? max : x;
48  }
49 };
50 
51 template <int min, int max>
53 {
54  template <class T>
55  static T apply( const T x )
56  {
57  if ( x < min )
58  return min;
59  else if ( x > max )
60  return max;
61  else
62  return x;
63  }
64 };
65 
66 /*
67  Class for emulating getter/setter. By itself it's not very useful, but will return
68  SafeInt<T> if USE_SAFEINT is defined. Can also be used for capping min/max values
69  via constraints. Also helps normalizing the interface to public variables, so that later on
70  we can change some of them (those which need updaters, for e.g.) to use getter/setters.
71 
72  If no constraints are used, has no impact on performance when compiled for release
73  compared to using a public variable.
74 
75  Example:
76 
77  class X {
78  ...
79  Property<u16> ar;
80  }
81 
82  X obj;
83 
84  int y = obj.ar(); // gets the value
85  obj.ar( 100 ); // sets the value
86 
87 */
88 template <class T, class constraint = NoConstraint>
89 class Property
90 {
91 private:
92  T _value;
93 
94 public:
95  Property( T x ) { _value = x; }
96  Property() { _value = 0; }
97 #ifdef USE_SAFEINT
98  SafeInt<T> operator()() const { return SafeInt<T>( _value ); }
99  SafeInt<T> operator()( const T newValue )
100  {
101  _value = constraint::apply<T>( newValue );
102  return SafeInt<T>( _value );
103  }
104 #else
105  T operator()() const { return _value; }
106  T operator()( const T newValue )
107  {
108  _value = constraint::apply<T>( newValue );
109  return _value;
110  }
111 #endif
112 
113  T unsafe() const { return _value; }
114 };
115 
116 
117 /*
118  Preprocessor macro for defining get/set of dynamic properties. This requires the object
119  to have the functions this->getProp<T,key>() and this->setProp<T,key>(newValue).
120 
121  Example:
122  PROPERTY_MAP( ar_mod, s16, MBR_AR_MOD );
123 
124  */
125 #define PROPERTY_MAP( propName, type, key ) \
126  type propName() const { return this->getmember<type, key>(); } \
127  type propName( type tmp ) \
128  { \
129  this->setmember<type, key>( tmp ); \
130  return tmp; \
131  }
132 
133 #endif
134 
135 #ifdef USE_SAFEINT
136 /*
137  The code below should go somewhere else. Right now (2013), property.h is the only thing to use
138  SafeInts.
139 */
140 struct PropertyHelper
141 {
142  static const char* stringFromError( SafeIntError x )
143  {
144  const int numberOfErrors = 3;
145  const char* SafeIntErrorString[numberOfErrors] = {"No error", "Arithmetic overflow",
146  "Divide by zero"};
147 
148  if ( x < numberOfErrors )
149  {
150  return SafeIntErrorString[x];
151  }
152  else
153  {
154  return "";
155  }
156  }
157 };
158 #endif
T operator()(const T newValue)
Definition: property.h:106
static T apply(const T x)
Definition: property.h:25
static T apply(const T x)
Definition: property.h:35
Property()
Definition: property.h:96
Property(T x)
Definition: property.h:95
static T apply(const T x)
Definition: property.h:55
T operator()() const
Definition: property.h:105
T unsafe() const
Definition: property.h:113
T _value
Definition: property.h:92
static T apply(const T x)
Definition: property.h:45