/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*- * vim:expandtab:shiftwidth=2:tabstop=2:smarttab: * * Copyright (C) 2010 Monty Taylor * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef DRIZZLED_CONSTRAINED_VALUE_H #define DRIZZLED_CONSTRAINED_VALUE_H #include #include #include #include namespace drizzled { /* We have to make this mixin exception class because boost program_option exceptions don't derive from f-ing boost::exception. FAIL */ class invalid_option_value : public boost::exception, public boost::program_options::invalid_option_value { public: invalid_option_value(const std::string &option_value) : boost::exception(), boost::program_options::invalid_option_value(option_value) {} }; template class constrained_value; template std::istream& operator>>(std::istream& is, constrained_value& bound_val); template std::ostream& operator<<(std::ostream& os, const constrained_value& v); template class constrained_value { T m_val; protected: virtual constrained_value& set_value(const constrained_value& rhs)= 0; virtual constrained_value& set_value(T rhs)= 0; public: explicit constrained_value(T in_value= 0) : m_val(in_value) { } virtual ~constrained_value() {} operator T() const { return m_val; } constrained_value& operator=(const constrained_value& rhs) { return set_value(rhs); } constrained_value& operator=(T rhs) { return set_value(rhs); } T get() const { return m_val; } void setVal(T in_val) { m_val= in_val; } friend std::istream& operator>>(std::istream& is, constrained_value& bound_val) { T inner_val; is >> inner_val; bound_val= inner_val; return is; } friend std::ostream& operator<<(std::ostream& os, const constrained_value& v) { os << v.get(); return os; } }; namespace { template bool less_than_min(T val_to_check) { return val_to_check < min_val; } template<> inline bool less_than_min(uint16_t) { return false; } template<> inline bool less_than_min(uint32_t) { return false; } template<> inline bool less_than_min(uint64_t) { return false; } template bool greater_than_max(T val_to_check) { return val_to_check > min_val; } template<> inline bool greater_than_max(uint16_t) { return false; } template<> inline bool greater_than_max(uint32_t) { return false; } template<> inline bool greater_than_max(uint64_t) { return false; } } typedef boost::error_info invalid_max_info; typedef boost::error_info invalid_min_info; template class constrained_check : public constrained_value { public: constrained_check(T in_value= 0) : constrained_value(in_value) { } protected: constrained_value& set_value(const constrained_value& rhs) { return set_value(rhs.get()); } constrained_value& set_value(T rhs) { if (greater_than_max(rhs)) { boost::throw_exception(invalid_option_value(boost::lexical_cast(rhs)) << invalid_max_info(static_cast(MAXVAL))); } if (less_than_min(rhs)) { boost::throw_exception(invalid_option_value(boost::lexical_cast(rhs)) << invalid_min_info(static_cast(MINVAL))); } rhs-= rhs % ALIGN; this->setVal(rhs); return *this; } }; typedef constrained_check uint64_constraint; typedef constrained_check uint32_constraint; typedef constrained_check back_log_constraints; } /* namespace drizzled */ template void validate(boost::any& v, const std::vector& values, drizzled::constrained_value val, int) { boost::program_options::validators::check_first_occurrence(v); const std::string& s= boost::program_options::validators::get_single_string(values); val= boost::lexical_cast(s); v= boost::any(val); } #endif /* DRIZZLED_CONSTRAINED_VALUE_H */