~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/constrained_value.h

  • Committer: Monty Taylor
  • Date: 2010-10-19 21:51:42 UTC
  • mto: This revision was merged to the branch mainline in revision 1870.
  • Revision ID: mordred@inaugust.com-20101019215142-bwof1oqrswj9ms3v
Add a constrained_value class which allows us to set compile-time
constraints on a value.

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
#ifndef DRIZZLED_CONSTRAINED_VALUE_H
21
21
#define DRIZZLED_CONSTRAINED_VALUE_H
22
22
 
23
 
#include <boost/exception/info.hpp>
24
23
#include <boost/program_options.hpp>
25
 
#include <boost/program_options/errors.hpp>
 
24
#include <boost/exception/all.hpp>
26
25
#include <iostream>
27
 
#include <netinet/in.h> /* for in_port_t */
28
26
 
29
27
namespace drizzled
30
28
{
31
29
 
32
 
/* We have to make this mixin exception class because boost program_option
33
 
  exceptions don't derive from f-ing boost::exception. FAIL
34
 
*/
35
 
class invalid_option_value :
36
 
  public boost::exception,
37
 
  public boost::program_options::invalid_option_value
38
 
{
39
 
public:
40
 
  invalid_option_value(const std::string &option_value) :
41
 
    boost::exception(),
42
 
    boost::program_options::invalid_option_value(option_value)
43
 
  {}
44
 
};
45
 
 
46
 
template<class T> class constrained_value;
47
 
template<class T>
48
 
std::istream& operator>>(std::istream& is, constrained_value<T>& bound_val);
49
 
template<class T>
50
 
std::ostream& operator<<(std::ostream& os, const constrained_value<T>& v);
51
 
 
52
30
template<class T>
53
31
class constrained_value
54
32
{
81
59
    return set_value(rhs);
82
60
  }
83
61
 
84
 
  T get() const
 
62
  T getVal() const
85
63
  {
86
64
    return m_val;
87
65
  }
91
69
    m_val= in_val;
92
70
  }
93
71
 
94
 
  friend std::istream&
95
 
  operator>>(std::istream& is,
 
72
  template<class CharT, class Traits>
 
73
  friend std::basic_istream<CharT,Traits>&
 
74
  operator>>(std::basic_istream<CharT,Traits>& is,
96
75
             constrained_value<T>& bound_val)
97
76
  {
98
77
    T inner_val;
104
83
  friend
105
84
  std::ostream& operator<<(std::ostream& os, const constrained_value<T>& v)
106
85
  {
107
 
    os << v.get();
 
86
    os << v.getVal();
108
87
    return os;
109
88
  }
110
89
};
111
90
 
112
 
namespace
113
 
{
114
 
template<class T, T min_val>
115
 
bool less_than_min(T val_to_check)
116
 
{
117
 
  return val_to_check < min_val;
118
 
}
119
 
 
120
 
template<>
121
 
inline bool less_than_min<uint16_t, 0>(uint16_t)
122
 
{
123
 
  return false;
124
 
}
125
 
 
126
 
template<>
127
 
inline bool less_than_min<uint32_t, 0>(uint32_t)
128
 
{
129
 
  return false;
130
 
}
131
 
 
132
 
template<>
133
 
inline bool less_than_min<uint64_t, 0>(uint64_t)
134
 
{
135
 
  return false;
136
 
}
137
 
 
138
 
template<class T, T min_val>
139
 
bool greater_than_max(T val_to_check)
140
 
{
141
 
  return val_to_check > min_val;
142
 
}
143
 
 
144
 
template<>
145
 
inline bool greater_than_max<uint16_t, UINT16_MAX>(uint16_t)
146
 
{
147
 
  return false;
148
 
}
149
 
 
150
 
template<>
151
 
inline bool greater_than_max<uint32_t, UINT32_MAX>(uint32_t)
152
 
{
153
 
  return false;
154
 
}
155
 
 
156
 
template<>
157
 
inline bool greater_than_max<uint64_t, UINT64_MAX>(uint64_t)
158
 
{
159
 
  return false;
160
 
}
161
 
162
 
 
163
 
typedef boost::error_info<struct tag_invalid_max,uint64_t> invalid_max_info;
164
 
typedef boost::error_info<struct tag_invalid_min,int64_t> invalid_min_info;
165
 
 
166
 
template<class T,
167
 
  T MAXVAL,
168
 
  T MINVAL, unsigned int ALIGN= 1>
 
91
template<class T, uint64_t MAXVAL=UINT64_MAX, int64_t MINVAL=INT64_MIN, int ALIGN=1>
169
92
class constrained_check :
170
93
  public constrained_value<T>
171
94
{
177
100
protected:
178
101
  constrained_value<T>& set_value(const constrained_value<T>& rhs)
179
102
  {
180
 
    return set_value(rhs.get());
 
103
    return set_value(rhs.getVal());
181
104
  }
182
105
 
183
106
  constrained_value<T>& set_value(T rhs)
184
107
  {
185
 
    if (greater_than_max<T,MAXVAL>(rhs))
186
 
    {
187
 
      boost::throw_exception(invalid_option_value(boost::lexical_cast<std::string>(rhs)) << invalid_max_info(static_cast<uint64_t>(MAXVAL)));
188
 
    }
189
 
      
190
 
    if (less_than_min<T,MINVAL>(rhs))
191
 
    {
192
 
      boost::throw_exception(invalid_option_value(boost::lexical_cast<std::string>(rhs)) << invalid_min_info(static_cast<int64_t>(MINVAL)));
 
108
    if ((rhs > MAXVAL) || (rhs < MINVAL))
 
109
    {
 
110
      boost::throw_exception(boost::program_options::validation_error(boost::program_options::validation_error::invalid_option_value));
193
111
    }
194
112
    rhs-= rhs % ALIGN;
195
 
    this->setVal(rhs);
 
113
    setVal(rhs);
196
114
    return *this;
197
115
  }
198
116
 
199
117
 
200
118
};
201
119
 
202
 
typedef constrained_check<uint64_t, UINT64_MAX, 0> uint64_constraint;
203
 
typedef constrained_check<uint32_t, UINT32_MAX, 0> uint32_constraint;
204
 
typedef constrained_check<uint64_t, UINT64_MAX, 1> uint64_nonzero_constraint;
205
 
typedef constrained_check<uint32_t, UINT32_MAX, 1> uint32_nonzero_constraint;
206
 
typedef drizzled::constrained_check<in_port_t, 65535, 0> port_constraint;
207
 
 
208
120
typedef constrained_check<uint32_t,65535,1> back_log_constraints;
209
121
 
210
122
} /* namespace drizzled */