00001
00002
00003
00004
00005
00006
00007
00008
00009 static const char rcsid[] __attribute__((used)) = "$Id: Interval.cpp 1197 2014-10-14 22:26:11Z sella $";
00010
00011 #include "Interval.h"
00012
00013 using namespace sella::variant;
00014
00015 const boost::regex Interval::Pattern("^(-?[0-9]+)([dhmsu])$");
00016
00017 Interval::Interval() throw () : Nullable() { }
00018
00019 Interval::Interval(const std::string &value) throw (TypeCastException) : Nullable() {
00020 boost::smatch matcher;
00021
00022 if (boost::regex_match(value, matcher, Interval::Pattern)) {
00023 int64_t usec;
00024
00025 try {
00026 usec = std::stoll(matcher[1].str().c_str());
00027 } catch (std::invalid_argument &e) {
00028 THROW(TypeCastException, "unable to cast '%s' to an interval value (invalid string)", value.c_str());
00029 } catch (std::out_of_range &e) {
00030 THROW(TypeCastException, "unable to cast '%s' to an interval value (overflow/underflow)", value.c_str());
00031 }
00032
00033 switch (matcher[2].str().c_str()[0]) {
00034 case 'd':
00035 usec *= 86400000000LL;
00036 break;
00037
00038 case 'h':
00039 usec *= 3600000000LL;
00040 break;
00041
00042 case 'm':
00043 usec *= 60000000LL;
00044 break;
00045
00046 case 's':
00047 usec *= 1000000LL;
00048 break;
00049
00050 case 'u':
00051 break;
00052
00053 default:
00054 THROW(TypeCastException, "unable to cast '%s' to an interval value", value.c_str());
00055 }
00056
00057 this->value = std::make_shared<uint64_t>(usec);
00058 } else {
00059 THROW(TypeCastException, "unable to cast '%s' to an interval value", value.c_str());
00060 }
00061 }
00062
00063 Interval::Interval(int64_t value) throw () : Nullable(std::make_shared<int64_t>(value)) { }
00064
00065 Interval::Interval(const Interval &other) throw () : Nullable(other) {
00066 if (!other.isNull()) {
00067 this->value = std::make_shared<int64_t>(*other.getUsec());
00068 }
00069 }
00070
00071 Interval::~Interval() throw () { }
00072
00073 bool Interval::operator==(const Interval &other) const throw () {
00074 return (*std::static_pointer_cast<int64_t>(this->value) == *std::static_pointer_cast<int64_t>(other.value));
00075 }
00076
00077 bool Interval::operator!=(const Interval &other) const throw () {
00078 return !(*this == other);
00079 }
00080
00081 bool Interval::operator>(const Interval &other) const throw () {
00082 return (*std::static_pointer_cast<int64_t>(this->value) > *std::static_pointer_cast<int64_t>(other.value));
00083 }
00084
00085 bool Interval::operator<(const Interval &other) const throw () {
00086 return (*std::static_pointer_cast<int64_t>(this->value) < *std::static_pointer_cast<int64_t>(other.value));
00087 }
00088
00089 Interval& Interval::operator=(const Interval &other) throw () {
00090 if (this != &other) {
00091 Nullable::operator=(other);
00092 if (!other.isNull()) {
00093 this->value = std::make_shared<int64_t>(*other.getUsec());
00094 }
00095 }
00096
00097 return *this;
00098 }
00099
00100 Interval& Interval::operator+=(int64_t value) throw () {
00101 cache.clear();
00102 (*std::static_pointer_cast<int64_t>(this->value)) += value;
00103
00104 return *this;
00105 }
00106
00107 Interval& Interval::operator-=(int64_t value) throw () {
00108 cache.clear();
00109 (*std::static_pointer_cast<int64_t>(this->value)) -= value;
00110
00111 return *this;
00112 }
00113
00114 Interval& Interval::operator*=(int64_t value) throw () {
00115 cache.clear();
00116 (*std::static_pointer_cast<int64_t>(this->value)) *= value;
00117
00118 return *this;
00119 }
00120
00121 Interval& Interval::operator/=(int64_t value) throw () {
00122 cache.clear();
00123 (*std::static_pointer_cast<int64_t>(this->value)) /= value;
00124
00125 return *this;
00126 }
00127
00128 Interval& Interval::operator^=(int64_t value) throw () {
00129 cache.clear();
00130 (*std::static_pointer_cast<int64_t>(this->value)) = pow((*std::static_pointer_cast<int64_t>(this->value)), value);
00131
00132 return *this;
00133 }
00134
00135 Interval& Interval::operator%=(int64_t value) throw () {
00136 cache.clear();
00137 (*std::static_pointer_cast<int64_t>(this->value)) %= value;
00138
00139 return *this;
00140 }
00141
00142 Interval& Interval::operator&=(int64_t value) throw () {
00143 cache.clear();
00144 (*std::static_pointer_cast<int64_t>(this->value)) &= value;
00145
00146 return *this;
00147 }
00148
00149 Interval& Interval::operator|=(int64_t value) throw () {
00150 cache.clear();
00151 (*std::static_pointer_cast<int64_t>(this->value)) |= value;
00152
00153 return *this;
00154 }
00155
00156 const int64_t* Interval::getUsec() const throw (UnsupportedOperatorException) {
00157 if (isNull()) {
00158 THROW(UnsupportedOperatorException, "unable to take reference of null value");
00159 }
00160
00161 return &(*std::static_pointer_cast<int64_t>(this->value));
00162 }
00163
00164 const std::string& Interval::str() const throw () {
00165 if (cache.empty()) {
00166 if (this->isNull()) {
00167 cache = "null";
00168 } else {
00169 char buffer[4096];
00170 int64_t usec = *(this->getUsec());
00171
00172 if ((usec % 3600000000LL) == 0) {
00173 snprintf(buffer, sizeof(buffer), "%lldh", usec % 3600000000LL);
00174 } else if ((usec % 60000000LL) == 0) {
00175 snprintf(buffer, sizeof(buffer), "%lldm", usec % 60000000LL);
00176 } else if ((usec % 1000000LL) == 0) {
00177 snprintf(buffer, sizeof(buffer), "%llds", usec % 1000000LL);
00178 } else {
00179 snprintf(buffer, sizeof(buffer), "%" PRId64 "u", usec);
00180 }
00181
00182 cache = buffer;
00183 }
00184 }
00185
00186 return cache;
00187 }
00188
00189
00190
00191