Drizzled Public API Documentation

constrained_value.h
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 #pragma once
21 
22 #include <boost/exception/info.hpp>
23 #include <boost/program_options.hpp>
24 #include <boost/program_options/errors.hpp>
25 #include <iosfwd>
26 #include <netinet/in.h> /* for in_port_t */
27 
28 namespace drizzled
29 {
30 
31 /* We have to make this mixin exception class because boost program_option
32  exceptions don't derive from f-ing boost::exception. FAIL
33 */
35  public boost::exception,
36  public boost::program_options::invalid_option_value
37 {
38 public:
39  invalid_option_value(const std::string &option_value) :
40  boost::exception(),
41  boost::program_options::invalid_option_value(option_value)
42  {}
43 };
44 
45 template<class T> class constrained_value;
46 template<class T>
47 std::istream& operator>>(std::istream& is, constrained_value<T>& bound_val);
48 template<class T>
49 std::ostream& operator<<(std::ostream& os, const constrained_value<T>& v);
50 
51 template<class T>
53 {
54  T m_val;
55 protected:
56 
57  virtual constrained_value<T>& set_value(const constrained_value<T>& rhs)= 0;
58  virtual constrained_value<T>& set_value(T rhs)= 0;
59 
60 public:
61  explicit constrained_value<T>(T in_value= 0) :
62  m_val(in_value)
63  { }
64 
65  virtual ~constrained_value<T>()
66  {}
67 
68  operator T() const
69  {
70  return m_val;
71  }
72 
73  constrained_value<T>& operator=(const constrained_value<T>& rhs)
74  {
75  return set_value(rhs);
76  }
77 
78  constrained_value<T>& operator=(T rhs)
79  {
80  return set_value(rhs);
81  }
82 
83  T get() const
84  {
85  return m_val;
86  }
87 
88  void setVal(T in_val)
89  {
90  m_val= in_val;
91  }
92 
93  friend std::istream&
94  operator>>(std::istream& is,
95  constrained_value<T>& bound_val)
96  {
97  T inner_val;
98  is >> inner_val;
99  bound_val= inner_val;
100  return is;
101  }
102 
103  friend
104  std::ostream& operator<<(std::ostream& os, const constrained_value<T>& v)
105  {
106  os << v.get();
107  return os;
108  }
109 };
110 
111 namespace
112 {
113 template<class T, T min_val>
114 bool less_than_min(T val_to_check)
115 {
116  return val_to_check < min_val;
117 }
118 
119 template<>
120 inline bool less_than_min<uint16_t, 0>(uint16_t)
121 {
122  return false;
123 }
124 
125 template<>
126 inline bool less_than_min<uint32_t, 0>(uint32_t)
127 {
128  return false;
129 }
130 
131 template<>
132 inline bool less_than_min<uint64_t, 0>(uint64_t)
133 {
134  return false;
135 }
136 
137 template<class T, T min_val>
138 bool greater_than_max(T val_to_check)
139 {
140  return val_to_check > min_val;
141 }
142 
143 template<>
144 inline bool greater_than_max<uint16_t, UINT16_MAX>(uint16_t)
145 {
146  return false;
147 }
148 
149 template<>
150 inline bool greater_than_max<uint32_t, UINT32_MAX>(uint32_t)
151 {
152  return false;
153 }
154 
155 template<>
156 inline bool greater_than_max<uint64_t, UINT64_MAX>(uint64_t)
157 {
158  return false;
159 }
160 }
161 
162 typedef boost::error_info<struct tag_invalid_max,uint64_t> invalid_max_info;
163 typedef boost::error_info<struct tag_invalid_min,int64_t> invalid_min_info;
164 typedef boost::error_info<struct tag_invalid_min,std::string> invalid_value;
165 
166 template<class T,
167  T MAXVAL,
168  T MINVAL, unsigned int ALIGN= 1>
170  public constrained_value<T>
171 {
172 public:
174  constrained_value<T>(in_value)
175  { }
176 
177 protected:
178  constrained_value<T>& set_value(const constrained_value<T>& rhs)
179  {
180  return set_value(rhs.get());
181  }
182 
183  constrained_value<T>& set_value(T rhs)
184  {
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)));
193  }
194  rhs-= rhs % ALIGN;
195  this->setVal(rhs);
196  return *this;
197  }
198 
199 
200 };
201 
207 
209 
210 } /* namespace drizzled */
211 
212 template<class T>
213 void validate(boost::any& v,
214  const std::vector<std::string>& values,
216 {
217  boost::program_options::validators::check_first_occurrence(v);
218  const std::string& s= boost::program_options::validators::get_single_string(values);
219 
220  val= boost::lexical_cast<T>(s);
221  v= boost::any(val);
222 }
223 
224 
TODO: Rename this file - func.h is stupid.