Tapkee
value_keeper.hpp
Go to the documentation of this file.
00001 /* This software is distributed under BSD 3-clause license (see LICENSE file).
00002  *
00003  * Copyright (c) 2012-2013 Sergey Lisitsyn
00004  */
00005 
00006 #ifndef TAPKEE_VALUE_KEEPER_H_
00007 #define TAPKEE_VALUE_KEEPER_H_
00008 
00009 /* Tapkee includes */
00010 #include <tapkee/parameters/policy.hpp>
00011 /* End of Tapkee includes */
00012 
00013 namespace tapkee
00014 {
00015 namespace tapkee_internal
00016 {
00017 
00018 struct EmptyType
00019 {
00020 };
00021 
00022 class ValueKeeper
00023 {
00024 
00025 public:
00026     template <typename T>
00027     explicit ValueKeeper(const T& value) : 
00028         policy(getPolicy<T>()), checker(getCheckerPolicy<T>()), value_ptr(NULL) 
00029     {
00030         policy->copyFromValue(&value, &value_ptr);
00031     }
00032 
00033     ValueKeeper() :
00034         policy(getPolicy<EmptyType>()), checker(getCheckerPolicy<EmptyType>()), value_ptr(NULL) 
00035     {
00036     }
00037 
00038     ~ValueKeeper()
00039     {
00040         policy->free(&value_ptr);
00041     }
00042 
00043     ValueKeeper(const ValueKeeper& v) : policy(v.policy), checker(v.checker), value_ptr(NULL)
00044     {
00045         policy->clone(&(v.value_ptr), &value_ptr);
00046     }
00047 
00048     ValueKeeper& operator=(const ValueKeeper& v)
00049     {
00050         policy->free(&value_ptr);
00051         policy = v.policy;
00052         checker = v.checker;
00053         policy->clone(&(v.value_ptr), &value_ptr);
00054         return *this;
00055     }
00056 
00057     template <typename T>
00058     inline T getValue() const
00059     {
00060         T* v;
00061         if (!isInitialized())
00062         {
00063             throw missed_parameter_error("Parameter is missed");
00064         }
00065         if (isTypeCorrect<T>())
00066         {
00067             void* vv = policy->getValue(const_cast<void**>(&value_ptr));
00068             v = reinterpret_cast<T*>(vv);
00069         }
00070         else
00071             throw wrong_parameter_type_error("Wrong value type");
00072         return *v;
00073     }
00074 
00075     template <typename T>
00076     inline bool isTypeCorrect() const
00077     {
00078         return getPolicy<T>() == policy;
00079     }
00080 
00081     inline bool isInitialized() const
00082     {
00083         return getPolicy<EmptyType>() != policy;
00084     }
00085 
00086     template <typename T>
00087     inline bool inRange(T lower, T upper) const
00088     {
00089         if (!isTypeCorrect<T>() && isInitialized())
00090             throw std::domain_error("Wrong range bounds type");
00091         return checker->isInRange(&value_ptr,&lower,&upper);
00092     }
00093 
00094     template <typename T>
00095     inline bool equal(T value) const
00096     {
00097         if (!isTypeCorrect<T>() && isInitialized())
00098             throw std::domain_error("Wrong equality value type");
00099         return checker->isEqual(&value_ptr,&value);
00100     }
00101 
00102     template <typename T>
00103     inline bool notEqual(T value) const
00104     {
00105         if (!isTypeCorrect<T>() && isInitialized())
00106             throw std::domain_error("Wrong non-equality value type");
00107         return checker->isNotEqual(&value_ptr,&value);
00108     }
00109 
00110     inline bool positive() const
00111     {
00112         return checker->isPositive(&value_ptr);
00113     }
00114 
00115     inline bool nonNegative() const
00116     {
00117         return checker->isNonNegative(&value_ptr);
00118     }
00119 
00120     inline bool negative() const
00121     {
00122         return checker->isNegative(&value_ptr);
00123     }
00124 
00125     inline bool nonPositive() const
00126     {
00127         return checker->isNonPositive(&value_ptr);
00128     }
00129 
00130     template <typename T>
00131     inline bool greater(T lower) const
00132     {
00133         if (!isTypeCorrect<T>() && isInitialized())
00134             throw std::domain_error("Wrong greater check bound type");
00135         return checker->isGreater(&value_ptr,&lower);
00136     }
00137 
00138     template <typename T>
00139     inline bool lesser(T upper) const
00140     {
00141         if (!isTypeCorrect<T>() && isInitialized())
00142             throw std::domain_error("Wrong lesser check bound type");
00143         return checker->isLesser(&value_ptr,&upper);
00144     }
00145 
00146 private:
00147 
00148     TypePolicyBase* policy;
00149     CheckerPolicyBase* checker;
00150     void* value_ptr;
00151 
00152 };
00153 
00154 }
00155 }
00156 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines