~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/constrained_value.h

  • Committer: Monty Taylor
  • Date: 2009-03-04 02:48:12 UTC
  • mto: (917.1.2 mordred)
  • mto: This revision was merged to the branch mainline in revision 918.
  • Revision ID: mordred@inaugust.com-20090304024812-5wb6wpye5c1iitbq
Applied atomic patch to current tree.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
 
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
 
 *
4
 
 *  Copyright (C) 2010 Monty Taylor
5
 
 *
6
 
 *  This program is free software; you can redistribute it and/or modify
7
 
 *  it under the terms of the GNU General Public License as published by
8
 
 *  the Free Software Foundation; version 2 of the License.
9
 
 *
10
 
 *  This program is distributed in the hope that it will be useful,
11
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 
 *  GNU General Public License for more details.
14
 
 *
15
 
 *  You should have received a copy of the GNU General Public License
16
 
 *  along with this program; if not, write to the Free Software
17
 
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18
 
 */
19
 
 
20
 
#ifndef DRIZZLED_CONSTRAINED_VALUE_H
21
 
#define DRIZZLED_CONSTRAINED_VALUE_H
22
 
 
23
 
#include <boost/exception/info.hpp>
24
 
#include <boost/program_options.hpp>
25
 
#include <boost/program_options/errors.hpp>
26
 
#include <iostream>
27
 
#include <netinet/in.h> /* for in_port_t */
28
 
 
29
 
namespace drizzled
30
 
{
31
 
 
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
 
template<class T>
53
 
class constrained_value
54
 
{
55
 
  T m_val;
56
 
protected:
57
 
 
58
 
  virtual constrained_value<T>& set_value(const constrained_value<T>& rhs)= 0;
59
 
  virtual constrained_value<T>& set_value(T rhs)= 0;
60
 
 
61
 
public:
62
 
  explicit constrained_value<T>(T in_value= 0) :
63
 
    m_val(in_value)
64
 
  { }
65
 
 
66
 
  virtual ~constrained_value<T>()
67
 
  {}
68
 
 
69
 
  operator T() const
70
 
  {
71
 
    return m_val;
72
 
  }
73
 
 
74
 
  constrained_value<T>& operator=(const constrained_value<T>& rhs)
75
 
  {
76
 
    return set_value(rhs);
77
 
  }
78
 
 
79
 
  constrained_value<T>& operator=(T rhs)
80
 
  {
81
 
    return set_value(rhs);
82
 
  }
83
 
 
84
 
  T get() const
85
 
  {
86
 
    return m_val;
87
 
  }
88
 
 
89
 
  void setVal(T in_val)
90
 
  {
91
 
    m_val= in_val;
92
 
  }
93
 
 
94
 
  friend std::istream&
95
 
  operator>>(std::istream& is,
96
 
             constrained_value<T>& bound_val)
97
 
  {
98
 
    T inner_val;
99
 
    is >> inner_val;
100
 
    bound_val= inner_val;
101
 
    return is;
102
 
  }
103
 
 
104
 
  friend
105
 
  std::ostream& operator<<(std::ostream& os, const constrained_value<T>& v)
106
 
  {
107
 
    os << v.get();
108
 
    return os;
109
 
  }
110
 
};
111
 
 
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
 
typedef boost::error_info<struct tag_invalid_min,std::string> invalid_value;
166
 
 
167
 
template<class T,
168
 
  T MAXVAL,
169
 
  T MINVAL, unsigned int ALIGN= 1>
170
 
class constrained_check :
171
 
  public constrained_value<T>
172
 
{
173
 
public:
174
 
  constrained_check<T,MAXVAL,MINVAL,ALIGN>(T in_value= 0) :
175
 
    constrained_value<T>(in_value)
176
 
  { }
177
 
 
178
 
protected:
179
 
  constrained_value<T>& set_value(const constrained_value<T>& rhs)
180
 
  {
181
 
    return set_value(rhs.get());
182
 
  }
183
 
 
184
 
  constrained_value<T>& set_value(T rhs)
185
 
  {
186
 
    if (greater_than_max<T,MAXVAL>(rhs))
187
 
    {
188
 
      boost::throw_exception(invalid_option_value(boost::lexical_cast<std::string>(rhs)) << invalid_max_info(static_cast<uint64_t>(MAXVAL)));
189
 
    }
190
 
      
191
 
    if (less_than_min<T,MINVAL>(rhs))
192
 
    {
193
 
      boost::throw_exception(invalid_option_value(boost::lexical_cast<std::string>(rhs)) << invalid_min_info(static_cast<int64_t>(MINVAL)));
194
 
    }
195
 
    rhs-= rhs % ALIGN;
196
 
    this->setVal(rhs);
197
 
    return *this;
198
 
  }
199
 
 
200
 
 
201
 
};
202
 
 
203
 
typedef constrained_check<uint64_t, UINT64_MAX, 0> uint64_constraint;
204
 
typedef constrained_check<uint32_t, UINT32_MAX, 0> uint32_constraint;
205
 
typedef constrained_check<uint64_t, UINT64_MAX, 1> uint64_nonzero_constraint;
206
 
typedef constrained_check<uint32_t, UINT32_MAX, 1> uint32_nonzero_constraint;
207
 
typedef drizzled::constrained_check<in_port_t, 65535, 0> port_constraint;
208
 
 
209
 
typedef constrained_check<uint32_t,65535,1> back_log_constraints;
210
 
 
211
 
} /* namespace drizzled */
212
 
 
213
 
template<class T>
214
 
void validate(boost::any& v,
215
 
              const std::vector<std::string>& values,
216
 
              drizzled::constrained_value<T> val, int)
217
 
{
218
 
  boost::program_options::validators::check_first_occurrence(v);
219
 
  const std::string& s= boost::program_options::validators::get_single_string(values);
220
 
 
221
 
  val= boost::lexical_cast<T>(s);
222
 
  v= boost::any(val);
223
 
}
224
 
 
225
 
 
226
 
#endif /* DRIZZLED_CONSTRAINED_VALUE_H */