function CATEGORY(array $t_args) { if (array_key_exists('dict', $t_args)) { $values = $t_args['dict']; $maxID = 0; foreach ($values as $id => $val) { $maxID = \max($id, $maxID); } } else { $old_vals = get_first_key($t_args, ['values', 0]); $startAt = get_first_key_default($t_args, ['start.at'], 0); $values = []; $maxID = $startAt; foreach ($old_vals as $ind => $val) { $values[$maxID++] = $val; } } $cardinality = \count($values); // Add 1 to the cardinality for the invalid id $storageTypeBits = ceil(log($maxID + 1, 2)); if ($storageTypeBits > 64) { // This should never happen. PHP would explode processing 2^64 values. grokit_error("Unable to store {$cardinality} values within 64 bits."); } else { if ($storageTypeBits > 32) { $storageType = 'uint64_t'; $storageBytes = 8; } else { if ($storageTypeBits > 16) { $storageType = 'uint32_t'; $storageBytes = 4; } else { if ($storageTypeBits > 8) { $storageType = 'uint16_t'; $storageBytes = 2; } else { $storageType = 'uint8_t'; $storageBytes = 1; } } } } $className = generate_name('CATEGORY'); $stringType = lookupType('base::STRING'); $methods = []; $constructors = []; $functions = []; ?> class <?php echo $className; ?> { public: typedef <?php echo $storageType; ?> StorageType; typedef std::unordered_map<StorageType, std::string> IDToNameMap; typedef std::unordered_map<std::string, StorageType> NameToIDMap; static const StorageType InvalidID __attribute__((weak)); private: static const IDToNameMap idToName __attribute__((weak)); static const NameToIDMap nameToID __attribute__((weak)); // The ID of this categorical variable StorageType myID; public: /* ----- Constructors / Destructor ----- */ <?php echo $className; ?> ( void ); <?php $constructors[] = [['base::STRING_LITERAL'], true]; ?> <?php echo $className; ?> ( const char * ); <?php $constructors[] = [['base::STRING'], true]; ?> <?php echo $className; ?> ( const <?php echo $stringType; ?> & ); <?php echo $className; ?> ( const <?php echo $storageType; ?> ); <?php echo $className; ?> ( const <?php echo $className; ?> & ); <?php $constructors[] = [['BASE::NULL'], true]; ?> <?php echo $className; ?> ( const GrokitNull & ); <?php echo $className; ?> & operator =( const <?php echo $className; ?> & ) = default; ~<?php echo $className; ?> (void) {} /* ----- Methods ----- */ void FromString( const char * ); <?php $methods[] = ['ToString', [], 'base::STRING_LITERAL', true]; ?> const char * ToString( void ) const; StorageType GetID( void ) const; void SetID( StorageType id ); // Determines whether or not the category is valid. <?php $methods[] = ['Invalid', [], 'base::bool', true]; ?> bool Invalid(void) const; <?php $methods[] = ['Valid', [], 'base::bool', true]; ?> bool Valid(void) const; /* ----- Operators ----- */ bool operator ==( const <?php echo $className; ?> & ) const; bool operator !=( const <?php echo $className; ?> & ) const; bool operator <( const <?php echo $className; ?> & ) const; bool operator <=( const <?php echo $className; ?> & ) const; bool operator >( const <?php echo $className; ?> & ) const; bool operator >=( const <?php echo $className; ?> & ) const; // Implicit conversion to storage type operator <?php echo $storageType; ?> () const; // To/From Json void toJson( Json::Value & dest ) const; void fromJson( const Json::Value & src ); }; /* ----- Constructors ----- */ inline <?php echo $className; ?> :: <?php echo $className; ?> ( void ) : myID(InvalidID) { } inline <?php echo $className; ?> :: <?php echo $className; ?> ( const char * str ) { FromString(str); } inline <?php echo $className; ?> :: <?php echo $className; ?> ( const <?php echo $stringType; ?> & str ) { FromString(str.ToString()); } inline <?php echo $className; ?> :: <?php echo $className; ?> ( const <?php echo $storageType; ?> val ) : myID(val) { } inline <?php echo $className; ?> :: <?php echo $className; ?> ( const <?php echo $className; ?> & other ) : myID(other.myID) { } inline <?php echo $className; ?> :: <?php echo $className; ?> ( const GrokitNull & nullval ) : myID(InvalidID) { } /* ----- Methods ----- */ inline void <?php echo $className; ?> :: FromString( const char * str ) { auto it = nameToID.find(str); if( it != nameToID.end() ) { myID = it->second; } else { myID = InvalidID; } } inline const char * <?php echo $className; ?> :: ToString( void ) const { auto it = idToName.find(myID); if( it != idToName.end() ) { return it->second.c_str(); } else { return "NULL"; } } inline auto <?php echo $className; ?> :: GetID( void ) const -> StorageType { return myID; } inline void <?php echo $className; ?> :: SetID( StorageType id ) { myID = id; } inline bool <?php echo $className; ?> :: Valid(void) const { return idToName.count(myID) > 0; } inline bool <?php echo $className; ?> :: Invalid(void) const { return ! Valid(); } /* ----- Operators ----- */ inline bool <?php echo $className; ?> :: operator ==( const <?php echo $className; ?> & other ) const { return myID == other.myID; } inline bool <?php echo $className; ?> :: operator !=( const <?php echo $className; ?> & other ) const { return myID != other.myID; } inline bool <?php echo $className; ?> :: operator <( const <?php echo $className; ?> & other ) const { return myID < other.myID; } inline bool <?php echo $className; ?> :: operator >( const <?php echo $className; ?> & other ) const { return myID > other.myID; } inline bool <?php echo $className; ?> :: operator <=( const <?php echo $className; ?> & other ) const { return myID <= other.myID; } inline bool <?php echo $className; ?> :: operator >=( const <?php echo $className; ?> & other ) const { return myID >= other.myID; } // To/From Json inline void <?php echo $className; ?> :: toJson( Json::Value & dest ) const { dest = (Json::Int64) myID; } inline void <?php echo $className; ?> :: fromJson( const Json::Value & src ) { myID = (StorageType) src.asInt64(); } inline <?php echo $className; ?> :: operator <?php echo $storageType; ?> () const { return myID; } <?php ob_start(); $functions[] = ['Hash', ['@type'], 'base::BIGINT', true, true]; ?> template<> inline uint64_t Hash(const @type & thing) { return thing.GetID(); } inline void FromString( @type & c, const char * str ) { c.FromString(str); } inline int ToString( const @type & c, char * buffer ) { const char * str = c.ToString(); strcpy( buffer, str); int len = strlen(buffer); return len + 1; } inline void ToJson( const @type & src, Json::Value & dest ) { src.toJson(dest); } inline void FromJson( const Json::Value & src, @type & dest ) { dest.fromJson(src); } <?php $functions[] = ['IsNull', ['@type'], 'BASE::BOOL', true, true]; ?> inline bool IsNull( const @type c ) { return c.Invalid(); } <?php $globalContents = ob_get_clean(); ?> // Initialize static values const <?php echo $className; ?> ::IDToNameMap <?php echo $className; ?> :: idToName = { <?php echo array_template('{{key},"{val}"}', ',', $values); ?> }; const <?php echo $className; ?> ::NameToIDMap <?php echo $className; ?> :: nameToID = { <?php echo array_template('{"{val}",{key}}', ',', $values); ?> }; const <?php echo $className; ?> ::StorageType <?php echo $className; ?> :: InvalidID = std::numeric_limits<<?php echo $className; ?> ::StorageType>::max(); <?php return ['kind' => 'TYPE', 'name' => $className, 'properties' => ['categorical'], 'extras' => ['cardinality' => $cardinality, 'size.bytes' => $storageBytes], 'binary_operators' => ['==', '!=', '<', '>', '<=', '>='], 'system_headers' => ['cinttypes', 'unordered_map', 'string', 'cstring', 'limits'], 'global_content' => $globalContents, 'complex' => false, 'methods' => $methods, 'constructors' => $constructors, 'functions' => $functions, 'describe_json' => DescribeJson('factor', DescribeJsonStatic(['levels' => $values]))]; }
function DATETIME() { $methods = []; $constructors = []; $functions = []; $bin_operators = []; $libraries = []; $system_headers = ['cinttypes', 'ctime', 'cstdio']; $system_headers[] = 'boost/date_time/posix_time/posix_time.hpp'; $system_headers[] = 'boost/date_time/gregorian/gregorian.hpp'; $system_headers[] = 'boost/date_time/dst_rules.hpp'; $libraries[] = 'boost_date_time'; $globalContent = ""; ?> class DATETIME { private: static constexpr const int32_t TM_YEAR_OFFSET = 1900; static constexpr const int32_t INVALID_DTIME = -1; static constexpr const int32_t S_PER_MIN = 60; static constexpr const int32_t S_PER_HR = S_PER_MIN * 60; static constexpr const int32_t S_PER_DAY = S_PER_HR * 24; // Each month is encoded in 5 bits, with january in the least significant // bits static constexpr const uint64_t DAYS_PER_MONTH = 0x0ffbfefffdff7f9f; static constexpr const uint8_t DPM_MASK = 0x1F; static constexpr const uint8_t DPM_BITS = 5; static const boost::posix_time::ptime UNIX_EPOCH __attribute__ ((weak)); int32_t ctime; void Set( int16_t year, int8_t month, int8_t day, int8_t hour, int8_t minute, int8_t second ); public: <?php $constructors[] = [[], true]; ?> constexpr DATETIME(void); <?php $constructors[] = [['BASE::INT'], true]; ?> constexpr DATETIME(const int32_t _ctime); <?php $constructors[] = [['BASE::NULL'], true]; ?> constexpr DATETIME(const GrokitNull & nullval); <?php $constructors[] = [['BASE::SMALLINT', 'BASE::BYTE', 'BASE::BYTE', 'BASE::BYTE', 'BASE::BYTE', 'BASE::BYTE'], true]; ?> DATETIME( int16_t year, int8_t month, int8_t day, int8_t hour, int8_t minute, int8_t second ); <?php $constructors[] = [['BASE::STRING_LITERAL'], true]; ?> DATETIME(const char * str); // Accessors for portions of the date <?php $methods[] = ['Year', [], 'BASE::SMALLINT', true]; ?> int16_t Year(void) const; <?php $methods[] = ['Month', [], 'BASE::BYTE', true]; ?> int8_t Month(void) const; <?php $methods[] = ['Day', [], 'BASE::BYTE', true]; ?> int8_t Day(void) const; <?php $methods[] = ['Hour', [], 'BASE::BYTE', true]; ?> int8_t Hour(void) const; <?php $methods[] = ['Minute', [], 'BASE::BYTE', true]; ?> int8_t Minute(void) const; <?php $methods[] = ['Second', [], 'BASE::BYTE', true]; ?> int8_t Second(void) const; <?php $methods[] = ['DayOfWeek', [], 'BASE::BYTE', true]; ?> int8_t DayOfWeek(void) const; <?php $methods[] = ['DayOfYear', [], 'BASE::SMALLINT', true]; ?> int16_t DayOfYear(void) const; // Returns the number of days in the date's month <?php $methods[] = ['DaysInMonth', [], 'BASE::BYTE', true]; ?> int8_t DaysInMonth(void) const; <?php $methods[] = ['AsDays', [], 'BASE::INT', true]; ?> constexpr int32_t AsDays(void) const; <?php $methods[] = ['AsHours', [], 'BASE::INT', true]; ?> constexpr int32_t AsHours(void) const; <?php $methods[] = ['AsMinutes', [], 'BASE::INT', true]; ?> constexpr int32_t AsMinutes(void) const; <?php $methods[] = ['AsSeconds', [], 'BASE::INT', true]; ?> constexpr int32_t AsSeconds(void) const; <?php $methods[] = ['IsValid', [], 'BASE::BOOL', true]; ?> constexpr bool IsValid(void) const; <?php $methods[] = ['IsNull', [], 'BASE::BOOL', true]; ?> constexpr bool IsNull(void) const; <?php $methods[] = ['IsDST', [], 'BASE::BOOL', true]; ?> bool IsDST(void) const; <?php $methods[] = ['IsDSTBoundary', [], 'BASE::BOOL', true]; ?> bool IsDSTBoundary(void) const; <?php $methods[] = ['GetDSTBoundary', [], 'BASE::BYTE', true]; ?> // Returns -1 if starting DST this day, // 1 if ending DST this day, // and 0 otherwise int8_t GetDSTBoundary(void) const; // Returns a new DATETIME with the time component set to 00:00:00 // and the day set to 1 <?php $methods[] = ['ByMonth', [], 'BASE::DATETIME', true]; ?> DATETIME ByMonth(void) const; // Comparisons <?php $bin_operators[] = '=='; ?> constexpr bool operator ==(const DATETIME & o) const; <?php $bin_operators[] = '!='; ?> constexpr bool operator !=(const DATETIME & o) const; <?php $bin_operators[] = '<'; ?> constexpr bool operator <(const DATETIME & o) const; <?php $bin_operators[] = '>'; ?> constexpr bool operator >(const DATETIME & o) const; <?php $bin_operators[] = '<='; ?> constexpr bool operator <=(const DATETIME & o) const; <?php $bin_operators[] = '>='; ?> constexpr bool operator >=(const DATETIME & o) const; constexpr bool operator ==(const int32_t secs) const; constexpr bool operator !=(const int32_t secs) const; constexpr bool operator <(const int32_t secs) const; constexpr bool operator >(const int32_t secs) const; constexpr bool operator <=(const int32_t secs) const; constexpr bool operator >=(const int32_t secs) const; // Adding / subtracting dates constexpr DATETIME operator +(const int32_t secs) const; constexpr DATETIME operator -(const int32_t secs) const; constexpr int32_t operator -(const DATETIME & o) const; void FromString( const char * str ); int ToString( char * buffer ) const; void FromJson( const Json::Value & ); void ToJson( Json::Value & ) const; // Static Members // static constexpr int8_t DaysInMonth(int16_t year, int8_t month); private: static constexpr int8_t GetDPM(int8_t month) { return (DAYS_PER_MONTH >> (month * DPM_BITS)) & DPM_MASK; } }; const boost::posix_time::ptime DATETIME::UNIX_EPOCH(boost::gregorian::date(1970, 1, 1)); inline constexpr int8_t DATETIME::DaysInMonth(int16_t year, int8_t month) { return (((month - 1) != 1) || (year % 4 != 0) || (year % 100 == 0 && year % 400 != 0)) ? GetDPM(month - 1) : GetDPM(month - 1) + 1; } inline void DATETIME :: Set( int16_t year, int8_t month, int8_t day, int8_t hour, int8_t minute, int8_t second ) { using boost::gregorian::date; using boost::posix_time::time_duration; using boost::posix_time::ptime; ptime time(date(year, month, day), time_duration(hour, minute, second)); long seconds = (time - UNIX_EPOCH).total_seconds(); ctime = int32_t(seconds); } inline constexpr DATETIME :: DATETIME(void) : ctime(INVALID_DTIME) { } inline constexpr DATETIME :: DATETIME(const int32_t _ctime) : ctime(_ctime) { } inline constexpr DATETIME :: DATETIME(const GrokitNull & nullval) : ctime(INVALID_DTIME) { } inline DATETIME :: DATETIME(const char * str) { this->FromString(str); } inline DATETIME :: DATETIME( int16_t year, int8_t month, int8_t day, int8_t hour, int8_t minute, int8_t second ) { Set(year, month, day, hour, minute, second); } inline int16_t DATETIME :: Year(void) const { auto temp = boost::posix_time::from_time_t(static_cast<time_t>(ctime)); return temp.date().year(); } inline int8_t DATETIME :: Month(void) const { auto temp = boost::posix_time::from_time_t(static_cast<time_t>(ctime)); return temp.date().month(); } inline int8_t DATETIME :: Day(void) const { auto temp = boost::posix_time::from_time_t(static_cast<time_t>(ctime)); return temp.date().day(); } inline int8_t DATETIME :: Hour(void) const { auto temp = boost::posix_time::from_time_t(static_cast<time_t>(ctime)); return temp.time_of_day().hours(); } inline int8_t DATETIME :: Minute(void) const { auto temp = boost::posix_time::from_time_t(static_cast<time_t>(ctime)); return temp.time_of_day().minutes(); } inline int8_t DATETIME :: Second(void) const { auto temp = boost::posix_time::from_time_t(static_cast<time_t>(ctime)); return temp.time_of_day().seconds(); } inline int8_t DATETIME :: DayOfWeek(void) const { auto temp = boost::posix_time::from_time_t(static_cast<time_t>(ctime)); return temp.date().day_of_week(); } inline int16_t DATETIME :: DayOfYear(void) const { auto temp = boost::posix_time::from_time_t(static_cast<time_t>(ctime)); return temp.date().day_of_year(); } inline int8_t DATETIME :: DaysInMonth(void) const { auto temp = boost::posix_time::from_time_t(static_cast<time_t>(ctime)); auto ymd = temp.date().year_month_day(); return DATETIME::DaysInMonth(ymd.year, ymd.month); } inline bool DATETIME :: IsDST(void) const { auto temp = boost::posix_time::from_time_t(static_cast<time_t>(ctime)); return boost::posix_time::us_dst::local_is_dst(temp.date(), temp.time_of_day()) == boost::date_time::is_in_dst; } inline bool DATETIME :: IsDSTBoundary(void) const { auto dtime = boost::posix_time::from_time_t(static_cast<time_t>(ctime)); return boost::posix_time::us_dst::is_dst_boundary_day(dtime.date()); } inline int8_t DATETIME :: GetDSTBoundary(void) const { using boost::posix_time::us_dst; auto dtime = boost::posix_time::from_time_t(static_cast<time_t>(ctime)); auto date = dtime.date(); if (date == us_dst::local_dst_start_day(date.year())) return -1; else if (date == us_dst::local_dst_end_day(date.year())) return 1; else return 0; } inline constexpr int32_t DATETIME :: AsDays(void) const { return ctime / S_PER_DAY; } inline constexpr int32_t DATETIME :: AsHours(void) const { return ctime / S_PER_HR; } inline constexpr int32_t DATETIME :: AsMinutes(void) const { return ctime / S_PER_MIN; } inline constexpr int32_t DATETIME :: AsSeconds(void) const { return ctime; } inline constexpr bool DATETIME :: IsValid(void) const { return ctime >= 0; } inline constexpr bool DATETIME :: IsNull(void) const { return ctime < 0; //> } inline DATETIME DATETIME :: ByMonth(void) const { auto temp = boost::posix_time::from_time_t(static_cast<time_t>(ctime)); auto date = temp.date(); return DATETIME(date.year(), date.month(), 1, 0, 0, 0); } inline constexpr bool DATETIME :: operator ==(const DATETIME & o) const { return ctime == o.ctime; } inline constexpr bool DATETIME :: operator !=(const DATETIME & o) const { return ctime != o.ctime; } inline constexpr bool DATETIME :: operator <(const DATETIME & o) const { return ctime < o.ctime; } inline constexpr bool DATETIME :: operator >(const DATETIME & o) const { return ctime > o.ctime; } inline constexpr bool DATETIME :: operator <=(const DATETIME & o) const { return ctime <= o.ctime; } inline constexpr bool DATETIME :: operator >=(const DATETIME & o) const { return ctime >= o.ctime; } inline constexpr bool DATETIME :: operator ==(const int32_t secs) const { return ctime == secs; } inline constexpr bool DATETIME :: operator !=(const int32_t secs) const { return ctime != secs; } inline constexpr bool DATETIME :: operator <(const int32_t secs) const { return ctime < secs; } inline constexpr bool DATETIME :: operator >(const int32_t secs) const { return ctime > secs; } inline constexpr bool DATETIME :: operator <=(const int32_t secs) const { return ctime <= secs; } inline constexpr bool DATETIME :: operator >=(const int32_t secs) const { return ctime >= secs; } inline constexpr DATETIME DATETIME :: operator +(const int32_t secs) const { return DATETIME(ctime + secs); } inline constexpr DATETIME DATETIME :: operator -(const int32_t secs) const { return DATETIME(ctime - secs); } inline constexpr int32_t DATETIME :: operator -( const DATETIME & o ) const { return ctime - o.ctime; } inline void DATETIME :: FromString( const char * str ) { using namespace boost::posix_time; /* short year; char month; char day; char hour; char minute; char second; sscanf(str, "%hd-%hhd-%hhd %hhd:%hhd:%hhd", &year, &month, &day, &hour, &minute, &second); */ ptime posixTime = time_from_string(str); ptime epoch(boost::gregorian::date(1970, 1, 1)); time_duration::sec_type x = (posixTime - epoch).total_seconds(); ctime = int32_t(x); } inline int DATETIME :: ToString( char * buffer ) const { tm dtime; time_t tmp = static_cast<time_t>(ctime); gmtime_r(&tmp, &dtime); const char * format = "%d-%02d-%02d %02d:%02d:%02d"; return 1+sprintf(buffer, format, dtime.tm_year + TM_YEAR_OFFSET, dtime.tm_mon + 1, dtime.tm_mday, dtime.tm_hour, dtime.tm_min, dtime.tm_sec ); } inline void DATETIME :: FromJson( const Json::Value & src ) { this->FromString(src.asCString()); } inline void DATETIME :: ToJson( Json::Value & dest ) const { char buffer[24]; this->ToString(buffer); dest = buffer; } <?php ob_start(); ?> inline void FromString( @type & date, const char * buffer ) { date.FromString( buffer ); } inline int ToString( const @type & date, char * buffer ) { return date.ToString(buffer); } inline int64_t ClusterValue(const @type& x){ // Cast to uint first so that the result is not sign extended uint32_t tmp = x.AsSeconds(); return tmp; } inline void FromJson( const Json::Value & src, @type & dest ) { dest.FromJson(src); } inline void ToJson( const @type & src, Json::Value & dest ) { src.ToJson(dest); } // Hash function <?php $functions[] = ['Hash', ['@type'], 'BASE::BIGINT', true, true]; ?> template<> inline uint64_t Hash( const @type& val ) { return val.AsSeconds(); } <?php $functions[] = ['IsNull', ['@type'], 'BASE::BOOL', true, true]; ?> inline bool IsNull( const @type & d ) { return d.IsNull(); } #ifdef _HAS_STD_HASH <?php $system_headers[] = 'functional'; ?> // C++11 STL-compliant hash struct specialization namespace std { template <> class hash<@type> { public: size_t operator () (const @type& key) const { return Hash(key); } }; } #endif // _HAS_STD_HASH <?php $globalContent .= ob_get_clean(); ?> <?php return ['kind' => 'TYPE', 'complex' => false, 'system_headers' => $system_headers, 'user_headers' => ['Config.h'], 'binary_operators' => $bin_operators, 'global_content' => $globalContent, 'constructors' => $constructors, 'methods' => $methods, 'functions' => $functions, 'libraries' => $libraries, 'properties' => ['clusterable'], 'describe_json' => DescribeJson('datetime', DescribeJsonStatic(['format' => 'YYYY-MM-DD HH:mm:ss'])), 'extras' => ['size.bytes' => 4]]; }
function HEX($t_args) { // The number of bytes encoded per string. $size = get_first_key($t_args, ['size', 0]); $className = 'Hex' . $size; $systemHeaders = ['cstdio', 'cstring']; $userHeaders = []; $libHeaders = []; $libraries = []; $constructors = []; $methods = []; $functions = []; $binaryOperators = []; $unaryOperators = []; $globalContent = ''; $complex = false; $properties = []; $extra = ['size.bytes' => $size]; $describeJson = DescribeJson('hex', DescribeJsonStatic(['size' => $size])); $globalContent = ''; ?> class <?php echo $className; ?> { public: // Lookup table per pair of hex digits. static constexpr const char lookup[256] __attribute__((weak)) = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; static constexpr const char to_char[16] __attribute__((weak)) = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; // The number of bytes encoded. static const constexpr size_t kSize = <?php echo $size; ?> ; // The length of decoded strings. static const constexpr size_t kLength = 2 * kSize; private: // The binary data corresponding to the encoded string. std::array<char, kSize> bytes; public: <?php $constructors[] = [[], true]; ?> <?php echo $className; ?> (); <?php $constructors[] = [['BASE::NULL'], true]; ?> <?php echo $className; ?> (const GrokitNull& nullval); <?php $constructors[] = [['BASE::STRING_LITERAL'], true]; ?> <?php echo $className; ?> (const char* str); <?php $methods[] = ['IsValid', [], 'BASE::BOOL', true]; ?> bool IsValid(void) const; <?php $methods[] = ['IsNull', [], 'BASE::BOOL', true]; ?> bool IsNull(void) const; <?php $binaryOperators[] = '=='; ?> bool operator ==(const <?php echo $className; ?> & other) const; <?php $binaryOperators[] = '!='; ?> bool operator !=(const <?php echo $className; ?> & other) const; void FromString(const char* str); int ToString(char* buffer) const; void FromJson(const Json::Value& src); void ToJson(Json::Value& dest) const; }; // Allocate storage for static variables constexpr const char <?php echo $className; ?> ::lookup[256]; constexpr const char <?php echo $className; ?> ::to_char[16]; inline <?php echo $className; ?> ::<?php echo $className; ?> () { bytes.fill(0); } inline <?php echo $className; ?> ::<?php echo $className; ?> (const GrokitNull& nullval) { bytes.fill(0); } inline <?php echo $className; ?> ::<?php echo $className; ?> (const char* str) { this->FromString(str); } inline bool <?php echo $className; ?> ::operator ==(const <?php echo $className; ?> & other) const { return std::memcmp(bytes.data(), other.bytes.data(), kSize); } inline bool <?php echo $className; ?> ::operator !=(const <?php echo $className; ?> & other) const { return !(*this == other); } inline void <?php echo $className; ?> ::FromString(const char* str) { size_t len = strlen(str); FATALIF(len != kLength, "Incorrectly sized string, expected %zu, got %zu: %s", kLength, len, str); for (size_t i = 0; i < kSize; i++) { char a = lookup[str[2 * i]]; char b = lookup[str[2 * i + 1]]; FATALIF(a < 0 || b < 0, "Illegal hex character: %c%c", str[2 * i], str[2 * i + 1]); bytes[i] = (a << 4) | b; } } inline int <?php echo $className; ?> ::ToString(char* buffer) const { for (size_t i = 0; i < kSize; i++) { char byte = bytes[i]; buffer[2 * i] = to_char[(byte >> 4) & 0x0F]; buffer[2 * i + 1] = to_char[byte & 0x0F]; } buffer[kLength] = '\0'; return 1 + kLength; } inline void <?php echo $className; ?> ::FromJson(const Json::Value& src) { this->FromString(src.asCString()); } inline void <?php echo $className; ?> ::ToJson(Json::Value& dest) const { char buffer[kLength + 1]; this->ToString(buffer); dest = buffer; } <?php ob_start(); ?> inline void FromString(@type& data, const char* buffer) { data.FromString(buffer);; } inline int ToString(const @type& data, char* buffer) { return data.ToString(buffer); } inline void FromJson(const Json::Value& src, @type& dest) { dest.FromJson(src); } inline void ToJson(const @type& src, Json::Value& dest) { src.ToJson(dest); } <?php $globalContent .= ob_get_clean(); ?> <?php return ['kind' => 'TYPE', 'name' => $className, 'complex' => $complex, 'system_headers' => $systemHeaders, 'user_headers' => $userHeaders, 'lib_headers' => $libHeaders, 'libraries' => $libraries, 'binary_operators' => $binaryOperators, 'unary_operators' => $unaryOperators, 'global_content' => $globalContent, 'constructors' => $constructors, 'methods' => $methods, 'functions' => $functions, 'libraries' => $libraries, 'properties' => $properties, 'extras' => $extra, 'describe_json' => $describeJson]; }
function CATEGORYSET($t_args) { // The dictionary of the associated factor. $dictionary = get_first_key($t_args, ['dictionary', 'dict', 0]); $values = array_values($dictionary); // The component types used. $category = lookupType('category', ['dict' => $dictionary]); $bitset = lookupType('bitset', ['values' => $values]); $size = $bitset->get('size.bytes'); // The name of the object type. $className = 'CategorySet' . $size; $systemHeaders = ['cstdio', 'cstring']; $userHeaders = []; $libHeaders = []; $libraries = []; $constructors = []; $methods = []; $functions = []; $binaryOperators = []; $unaryOperators = []; $globalContent = ''; $complex = false; $properties = []; $extra = ['size.bytes' => $size]; $describeJson = DescribeJson('categoryset', DescribeJsonStatic(['levels' => $values])); $globalContent = ''; ?> class <?php echo $className; ?> { public: using Category = <?php echo $category; ?> ; using BitSet = <?php echo $bitset; ?> ; using StorageType = BitSet::StorageType; private: // The binary data corresponding to the encoded string. BitSet data; public: <?php $constructors[] = [[], true]; ?> <?php echo $className; ?> (); <?php $constructors[] = [['BASE::NULL'], true]; ?> <?php echo $className; ?> (const GrokitNull& null); <?php $constructors[] = [['BASE::STRING_LITERAL'], true]; ?> <?php echo $className; ?> (const char* str); <?php echo $className; ?> (const BitSet& data); <?php echo $className; ?> (const <?php echo $className; ?> & other); <?php $methods[] = ['IsEmpty', [], 'BASE::BOOL', true]; ?> bool IsEmpty() const; <?php echo $className; ?> & operator =(const <?php echo $className; ?> & other) = default; <?php $binaryOperators[] = '=='; ?> bool operator ==(const <?php echo $className; ?> & other) const; <?php $binaryOperators[] = '!='; ?> bool operator !=(const <?php echo $className; ?> & other) const; <?php $binaryOperators[] = '<'; ?> bool operator <(const <?php echo $className; ?> & other) const; <?php $binaryOperators[] = '>'; ?> bool operator >(const <?php echo $className; ?> & other) const; <?php $binaryOperators[] = '<='; ?> bool operator <=(const <?php echo $className; ?> & other) const; <?php $binaryOperators[] = '>='; ?> bool operator >=(const <?php echo $className; ?> & other) const; void FromString(const char* str); int ToString(char* buffer) const; void FromJson(const Json::Value& src); void ToJson(Json::Value& dest) const; }; inline <?php echo $className; ?> ::<?php echo $className; ?> () : data() { } inline <?php echo $className; ?> ::<?php echo $className; ?> (const GrokitNull& null) : data() { } inline <?php echo $className; ?> ::<?php echo $className; ?> (const char* str) { this->FromString(str); } inline <?php echo $className; ?> ::<?php echo $className; ?> (const <?php echo $className; ?> ::BitSet& data) : data(data) { } inline <?php echo $className; ?> ::<?php echo $className; ?> (const <?php echo $className; ?> & other) : data(other.data) { } inline bool <?php echo $className; ?> ::IsEmpty() const { return data == 0; } inline bool <?php echo $className; ?> ::operator ==(const <?php echo $className; ?> & other) const { return this->data == other.data; } inline bool <?php echo $className; ?> ::operator !=(const <?php echo $className; ?> & other) const { return this->data != other.data; } inline bool <?php echo $className; ?> ::operator <(const <?php echo $className; ?> & other) const { return this->data < other.data; } inline bool <?php echo $className; ?> ::operator >(const <?php echo $className; ?> &other) const { return this->data > other.data; } inline bool <?php echo $className; ?> ::operator <=(const <?php echo $className; ?> & other) const { return this->data <= other.data; } inline bool <?php echo $className; ?> ::operator >=(const <?php echo $className; ?> & other) const { return this->data >= other.data; } inline void <?php echo $className; ?> ::FromString(const char* str) { StorageType mask; char* storage; char* copy = strdup(str); char* token = strtok_r(copy, " ", &storage); while (token != NULL) { Category level (token); WARNINGIF(level.Invalid(), "Invalid token: %s", token); mask |= 1 << level; token = strtok_r(NULL, " ", &storage); } data = mask; free(copy); } inline int <?php echo $className; ?> ::ToString(char* buffer) const { char* start = buffer; <?php foreach ($dictionary as $name) { ?> if (data.<?php echo $name; ?> ()) buffer += sprintf(buffer, "%s ", "<?php echo $name; ?> "); <?php } ?> if (start == buffer) { buffer[0] = '\0'; return 1; } else { buffer[-1] = '\0'; return buffer - start; } } inline void <?php echo $className; ?> ::FromJson(const Json::Value& src) { this->FromString(src.asCString()); } inline void <?php echo $className; ?> ::ToJson(Json::Value& dest) const { char* buffer; this->ToString(buffer); dest = buffer; } <?php ob_start(); ?> inline void FromString(@type& data, const char* buffer) { data.FromString(buffer); } inline int ToString(const @type& data, char* buffer) { return data.ToString(buffer); } inline void FromJson(const Json::Value& src, @type& dest) { dest.FromJson(src); } inline void ToJson(const @type& src, Json::Value& dest) { src.ToJson(dest); } <?php $globalContent .= ob_get_clean(); ?> <?php return ['kind' => 'TYPE', 'name' => $className, 'complex' => $complex, 'system_headers' => $systemHeaders, 'user_headers' => $userHeaders, 'lib_headers' => $libHeaders, 'libraries' => $libraries, 'binary_operators' => $binaryOperators, 'unary_operators' => $unaryOperators, 'global_content' => $globalContent, 'constructors' => $constructors, 'methods' => $methods, 'functions' => $functions, 'libraries' => $libraries, 'properties' => $properties, 'extras' => $extra, 'describe_json' => $describeJson]; }
function DATE() { $methods = []; $constructors = []; $functions = []; ?> //--------------------------------------------------------------------------- // // Description: // DATE is a class for representing standard Gregorian calendar dates. // // Author: Rob Mueller // Date: 25-Jul-2001 // Modifications : SS : All code is inlined // // Multithread Safe: No (with conditions, see below) // Mutable Variables: Yes // // Copyright: // Copyright (c) 2001 by Robert Mueller. // // Permission to use, // copy, modify, distribute and sell this software and its // documentation for any purpose is hereby granted without fee, // provided that the above copyright notice appear in all copies // and that both that copyright notice and this permission notice // appear in supporting documentation. I make no representations // about the suitability of this software for any purpose. It is // provided "as is" without express or implied warranty. // // Remarks: // // DATE consists purely of date information. No time // information is associated with it. It can be broken down into: // * Year // * Month // * Day // * Day of Year // * Week of Year // * Year of "week of year" // * Day of Week // // See below for details on 'week of year' curiosities // // Trying to create an invalid date (eg. 29th Feb in a non-leap year) is // not validated, but is asserted in debug mode. The default constructor // creates the date with julian day 0. You can't convert this to a // year/month/day because it is out of range. The current system date // can be obtained with the static method DATE::GetSystemDate(). DATE // uses the pivot year set in the DATECalc class to convert 2 digit // years to 4 digit years. See DATECalc for more information. // // Where possible, DATE uses the International Standard ISO 8601. // This is mostly in the definition of the week of year component // of a date. See http://www.cl.cam.ac.uk/~mgk25/iso-time.html // for some useful docs. // // DATE differences can be calculated and a signed Int32 value is // used to represent the number of days difference between any two // dates. // // Implementation notes: // // Internally, the date is represented in one of two forms: // * A Julian day number // * A series of date components: year, day of year, etc // // These are stored in a single 32 bit integer. // The most significant bit determines if the structure is currently in // 'Julain day' representation mode or 'date parts' representation mode. // // The internal representation can be changed by calling the // InternalToDate() or InternalToJD() methods. These methods are // const, but do modify the internal values of the class because the // m_Date member variable is mutable. // // In general, when calling a routine that wants a 'Julian day' value // (eg GetJulianDay(), operator+(), etc), the internal representation // is first converted to 'Julian day' and the operation performed. // Similarily, calling a routine that wants a 'date part' (eg GetYear(), // GetMonth(), etc), the internal representation is first converted // to 'date parts' and then the appropriate value returned. This seems // to give good performance, because you tend to use methods that // require a particular representation near each other. // // Week of year oddities: // Week 01 of a year is per definition the first week that has the Thursday // in this year, which is equivalent to the week that contains the fourth // day of January. In other words, the first week of a new year is the week // that has the majority of its days in the new year // // The week of the year is odd in that week 01 might also contain days from // the previous year and the week before week 01 of a year is the last week // (52 or 53) of the previous year even if it contains days from the new year. // A week starts with Monday (day 1) and ends with Sunday (day 7). For example, // the first week of the year 1997 lasts from 1996-12-30 to 1997-01-05 // // Multithread safety: // // Because even const DATE objects can have their internal // representation changed, a DATE object is not-thread safe, even // as a const read only object! If you know what you're doing, you // can ensure you call InternalToDate() or InternalToJD() methods // and then only access methods that use that internal representation // in a multi-threaded environment // //--------------------------------------------------------------------------- // class DATE { public: // Group=Constructors // Description: Constructors. // Arguments: // copy - DATE object to create copy from // jd - Julian day number // year - year date represents. Years (00-99) converted to 4 digit year. // month - month of year date represents (1..12) // day - day of month date represents (1..28/29/30/31) // yearDay - day of year date represents (1-365/366 if leap year) inline DATE(const DATE & copy) : m_Date(copy.m_Date) {} <?php $constructors[] = [['base::INT'], true]; ?> inline DATE(const Int32 julianDay = 0) : m_Date(julianDay) { assert(julianDay >= 0); } <?php $constructors[] = [['base::INT', 'base::INT', 'base::INT'], true]; ?> DATE(Int32 year, Int32 month, Int32 day); <?php $constructors[] = [['base::INT', 'base::INT'], true]; ?> DATE(Int32 year, Int32 yearDay); <?php $constructors[] = [['BASE::NULL'], true]; ?> DATE(const GrokitNull & n); // Description: Returns a DATE instance that represents the current local system date. static DATE GetSystemDate(); // Group=Destructor inline ~DATE() {} // Group=Public Operators // Description: assignment inline DATE& operator=(const DATE& assign) { m_Date = assign.m_Date; return *this; } // Description: Test if dates equal bool operator==(const DATE & compare) const; // Description: Test if one date less than bool operator<(const DATE & compare) const; bool operator>(const DATE & compare) const; bool operator<=(const DATE & compare) const; bool operator>=(const DATE & compare) const; // Description: Add days to date and return new date // Arguments: // dateOffset - number of days to add to date (can be negative) DATE operator+(Int32 dateOffset) const; // Description: Subraction operators // Arguments: // dateOffset - Number of days to subtract from date (can be negative) // otherDate - Date to subtract. Returns number of days between dates DATE operator-(Int32 dateOffset) const; Int32 operator-( const DATE & otherDate) const; // Description: Add given number of days to current date // Arguments: // dateOffset - Number of days to add to current date (can be negative) DATE& operator+=(Int32 dateOffset); // Description: Subtract given number of days from current date // Arguments: // dateOffset - Number of days to subtract from date (can be negative) DATE& operator-=(Int32 dateOffset); // Group=Public Member Functions <?php $methods[] = ['IsNull', [], 'BASE::BOOL', true]; ?> bool IsNull(void) const; <?php $methods[] = ['IsLeapYear', [], 'BASE::BOOL', true]; ?> bool IsLeapYear() const; // Description: Returns the year represented by this date (1500-2500) <?php $methods[] = ['GetYear', [], 'base::INT', true]; ?> Int32 GetYear() const; // Description: Returns the quarter represented by this date (1-4) <?php $methods[] = ['GetQuarter', [], 'base::INT', true]; ?> Int32 GetQuarter() const; // Description: Returns the month in the year represented by this date (1-12) <?php $methods[] = ['GetMonth', [], 'base::INT', true]; ?> Int32 GetMonth() const; // Description: Returns the day in the month represented by this date (1-31) <?php $methods[] = ['GetDay', [], 'base::INT', true]; ?> Int32 GetDay() const; // Description: Returns the day of the year represented by this date (1-365, 366 if leap year) <?php $methods[] = ['GetDayOfYear', [], 'base::INT', true]; ?> Int32 GetDayOfYear() const; // Description: Returns the week of the year reprsented by this date (1-53). // See DATE class description for more details <?php $methods[] = ['GetWeekOfYear', [], 'base::INT', true]; ?> Int32 GetWeekOfYear() const; // Description: Returns the year of for the current week of the year. This // may be different to GetYear() for certain cross-over days. // See DATE class description for more details <?php $methods[] = ['GetYearForWeekOfYear', [], 'base::INT', true]; ?> Int32 GetYearForWeekOfYear() const; // Description: Returns the weekday of the week represented by this date // (1-7) => (Monday-Sunday) <?php $methods[] = ['GetDayOfWeek', [], 'base::INT', true]; ?> Int32 GetDayOfWeek() const; // Description: Return Julian day number <?php $methods[] = ['GetJulianDay', [], 'base::INT', true]; ?> Int32 GetJulianDay() const; <?php $methods[] = ['IsDST', [], 'BASE::BOOL', true]; ?> bool IsDST() const; // Description: //stl::string DATE::ToString() const; //bool FromString(const stl::string & dateString); int ToString(char* text) const; void FromString(const char* dateString); // Description: Convert internal representation to Julian day number void InternalToJD() const; // Description: Convert internal representation to date parts void InternalToDate() const; // Below functions added by me : SS /* Constructor from string "yyyy/mm/dd". The format is fixed */ <?php $constructors[] = [['base::STRING_LITERAL'], true]; ?> DATE (const char *_date){ FromStringYMD(_date); } void FromStringYMD(const char *_date) { // FIXME: we do not check if the date is valid int yy = (_date[0]-'0')*1000+(_date[1]-'0')*100+(_date[2]-'0')*10+(_date[3]-'0'); int mm = (_date[5]-'0')*10+(_date[6]-'0'); int dd = (_date[8]-'0')*10+(_date[9]-'0'); FromYMD(yy,mm,dd); } void FromYMD(Int32 year, Int32 month, Int32 day ) { // FIXME: we do not check if the date is valid (too complicated) m_Date = (Int32)DATECalc::CalcJulianPeriod(year, month, day); } void Print(void){ printf("%4d/%2d/%2d", GetYear(), GetMonth(), GetDay()); } private: // Group=Private Member Data // Description: The actual date, stored as either Julian day number or // as actual date components depending on highest bit // // Item Value Bits Bit // Range required offset // Storage type 0-1 1 31 // Is leap year? 0-1 1 30 // Week year difference -1 - 1 2 28-29 // Month 1-12 4 24-27 // Day of week 1-7 3 21-23 // Day 1-31 5 16-20 // Week of year 1-53 6 10-15 // Year 1500-2500 10 0-9 mutable Int32 m_Date; }; /******************* Here goes the inline cc code **************************/ #if defined(_MSC_VER) #pragma warning(disable: 4127) #endif // Macro to ensure internal representation is as Julian day #define REPASJD(obj) \ do { \ if ((obj).m_Date < 0) \ (obj).InternalToJD(); \ } while (0) // Macro to ensure internal representation is as date components #define REPASDATE(obj) \ do { \ if ((obj).m_Date >= 0) \ (obj).InternalToDate(); \ } while (0) #define BITOFFSETYEAR 0 #define BITSIZEYEAR 10 #define BITOFFSETWEEKOFYEAR 10 #define BITSIZEWEEKOFYEAR 6 #define BITOFFSETDAY 16 #define BITSIZEDAY 5 #define BITOFFSETDAYOFWEEK 21 #define BITSIZEDAYOFWEEK 3 #define BITOFFSETMONTH 24 #define BITSIZEMONTH 4 #define BITOFFSETWEEKYEARDIF 28 #define BITSIZEWEEKYEARDIF 2 #define BITOFFSETISLEAPYEAR 30 #define BITSIZEISLEAPYEAR 1 // We're using 10 bits to store the year (1024 years). Set the minimum year #define MINIMUMYEAR 1500 // Macro to extract bitfield component at offset of length from v #define GETCOMPONENT(v, offset, length) ( (v)>>(offset) & ((1<<(length))-1) ) //> // Table which maps month number to non-leap year day number of the first day of that month const static Int32 s_YearDayFromMonth[] = { 0, 1, 32, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }; inline DATE::DATE(Int32 year, Int32 month, Int32 day) { m_Date = (Int32)DATECalc::CalcJulianPeriod(year, month, day); } inline DATE::DATE(Int32 year, Int32 dayOfYear) { m_Date = (Int32)DATECalc::CalcJulianPeriod(year, dayOfYear); } inline DATE::DATE(const GrokitNull & n) { // All 1s is never valid, as that would have more weeks than in a year, // etc. m_Date = 0xFFFFFFFF; } inline bool DATE::IsNull(void) const { return m_Date == 0xFFFFFFFF; } inline DATE DATE::GetSystemDate() { // TODO: Get this to work return 0;//DATE(Int32(time(0) / 86400)); } inline bool DATE::operator==(const DATE & compare) const { // Ensure the internal representation of both objects is as days REPASJD(*this); REPASJD(compare); // Simple day compare return m_Date == compare.m_Date; } inline bool DATE::operator<(const DATE & compare) const { // Ensure the internal representation of both objects is as days REPASJD(*this); REPASJD(compare); // Simple day compare return m_Date < compare.m_Date; } inline bool DATE::operator>(const DATE & compare) const { // Ensure the internal representation of both objects is as days REPASJD(*this); REPASJD(compare); // Simple day compare return m_Date > compare.m_Date; } inline bool DATE::operator<=(const DATE & compare) const { // Ensure the internal representation of both objects is as days REPASJD(*this); REPASJD(compare); // Simple day compare return m_Date <= compare.m_Date; } inline bool DATE::operator>=(const DATE & compare) const { // Ensure the internal representation of both objects is as days REPASJD(*this); REPASJD(compare); // Simple day compare return m_Date >= compare.m_Date; } inline DATE DATE::operator+( Int32 dateOffset) const { return DATE(GetJulianDay() + dateOffset); } inline DATE DATE::operator-( Int32 dateOffset) const { return DATE(GetJulianDay() - dateOffset); } inline Int32 DATE::operator-( const DATE& otherDate) const { // Ensure the internal representation of both objects is as days REPASJD(*this); REPASJD(otherDate); return m_Date - otherDate.m_Date; } // Description: Self addition operator inline DATE& DATE::operator+=( Int32 dateOffset) { REPASJD(*this); m_Date += dateOffset; assert(m_Date >= 0); return *this; } // Description: Self subtraction operator inline DATE& DATE::operator-=( Int32 dateOffset) { REPASJD(*this); m_Date -= dateOffset; assert(m_Date >= 0); return *this; } inline bool DATE::IsLeapYear() const { REPASDATE(*this); return GETCOMPONENT(m_Date, BITOFFSETISLEAPYEAR, BITSIZEISLEAPYEAR) ? true : false; } // Description: Returns the year represented by this date (1500-2500) inline Int32 DATE::GetYear() const { REPASDATE(*this); Int32 Year = GETCOMPONENT(m_Date, BITOFFSETYEAR, BITSIZEYEAR) + MINIMUMYEAR; assert(Year >= MINIMUMYEAR && Year <= MINIMUMYEAR + 1000); //> return Year; } // Description: Returns the quarter represented by this date (1-4) inline Int32 DATE::GetQuarter() const { REPASDATE(*this); Int32 Quarter = GETCOMPONENT(m_Date, BITOFFSETMONTH, BITSIZEMONTH) / 3; assert(Quarter >= 1 && Quarter <= 4); //> return Quarter; } // Description: returns the month in the year represented by this date (1-12) inline Int32 DATE::GetMonth() const { REPASDATE(*this); Int32 Month = GETCOMPONENT(m_Date, BITOFFSETMONTH, BITSIZEMONTH); assert(Month >= 1 && Month <= 12); //> return Month; } // Description: returns the day in the month represented by this date (1-31) inline Int32 DATE::GetDay() const { REPASDATE(*this); Int32 Day = GETCOMPONENT(m_Date, BITOFFSETDAY, BITSIZEDAY); assert(Day >= 1 && Day <= DATECalc::DaysInMonth(GetMonth(), GETCOMPONENT(m_Date, BITOFFSETISLEAPYEAR, BITSIZEISLEAPYEAR) ? true : false)); return Day; } // Description: returns the day of the year represented by this date (1-365, 366 if leap year) inline Int32 DATE::GetDayOfYear() const { REPASDATE(*this); Int32 Month = GETCOMPONENT(m_Date, BITOFFSETMONTH, BITSIZEMONTH); // 1 - 12 Int32 DayOfYear = s_YearDayFromMonth[Month] + GETCOMPONENT(m_Date, BITOFFSETDAY, BITSIZEDAY) + (GETCOMPONENT(m_Date, BITOFFSETISLEAPYEAR, BITSIZEISLEAPYEAR) & (Month > 2)) - 1; assert(DayOfYear >= 1 && DayOfYear <= 365 + GETCOMPONENT(m_Date, BITOFFSETISLEAPYEAR, BITSIZEISLEAPYEAR)); return DayOfYear; } // Description: returns the week of the year reprsented by this date (1-52) inline Int32 DATE::GetWeekOfYear() const { REPASDATE(*this); Int32 WeekOfYear = GETCOMPONENT(m_Date, BITOFFSETWEEKOFYEAR, BITSIZEWEEKOFYEAR); assert(WeekOfYear >= 1 && WeekOfYear <= 53); return WeekOfYear; } // Description: Returns the year of for the current week of the year. This // may be different to GetYear() for certain cross-over days. // See DATE class description for more details inline Int32 DATE::GetYearForWeekOfYear() const { REPASDATE(*this); Int32 Year = GETCOMPONENT(m_Date, BITOFFSETYEAR, BITSIZEYEAR) + MINIMUMYEAR; Int32 YearOffset = GETCOMPONENT(m_Date, BITOFFSETWEEKYEARDIF, BITSIZEWEEKYEARDIF) - 1; assert(YearOffset >= -1 && YearOffset <= 1); return Year + YearOffset; } // Description: Returns the weekday of the week represented by this date (1-7) => (Monday-Sunday) inline Int32 DATE::GetDayOfWeek() const { REPASDATE(*this); Int32 DayOfWeek = GETCOMPONENT(m_Date, BITOFFSETDAYOFWEEK, BITSIZEDAYOFWEEK); assert(DayOfWeek >= 1 && DayOfWeek <= 7); // > return DayOfWeek; } // Description: convert to tstring (overrides CBasicTypeBase::ToTString) inline int DATE::ToString(char* text) const { // Use ISO YYYY/MM/DD format return 1+sprintf(text, "%04d/%02d/%02d", int(GetYear()), int(GetMonth()), int(GetDay())); } // Description: Convert from string (ISO 8601 format YYYY-MM-DD) inline void DATE::FromString(const char* dateString) { int Year = 0, Month = 0, Day = 0; sscanf(dateString, "%d/%d/%d", &Year, &Month, &Day); // assert if not valid date format assert (!((Year == 0) | (Month == 0) | (Day == 0))); *this = DATE(Year, Month, Day); } // Description: Return Julian day number inline Int32 DATE::GetJulianDay() const { REPASJD(*this); return m_Date; } inline bool DATE::IsDST() const { auto year = GetYear(); auto month = GetMonth(); auto day = GetDay(); if (year >= 2007) { // 2007+ rules // Begins at 2:00 AM on the second Sunday of March // Ends at 2:00 AM on the first Sunday of November if (month >= 4 || month <= 10) // > April through October are DST return true; else if (month <= 2 || month == 12) // > January, February and December are not DST return false; else if (month == 3) { // March DST starts // Find second sunday of march DATE firstDay(year, month, 1); Int32 daysTillSunday = 7 - firstDay.GetDayOfWeek(); // Add 7 days to first sunday to get second sunday Int32 secondSunday = 1 + daysTillSunday + 7; return day >= secondSunday; } else if (month == 11) { // November DST ends // Find first sunday of november DATE firstDay(year, month, 1); Int32 daysTillSunday = 7 - firstDay.GetDayOfWeek(); Int32 firstSunday = 1 + daysTillSunday; return day < firstSunday; // > } else { return false; } } else if (year >= 1987) { // Old DST rules // Begins at 2:00 AM on the first Sunday of April // Ends at 2:00 AM on the last Sunday of October if (month >= 5 || month <= 9) // > May through September are DST return true; else if (month <= 3 || month >= 11) // > January, February, March, November, and December are not DST return false; else if (month == 4) { // April DST starts // Find first sunday of april DATE firstDay(year, month, 1); Int32 daysTillSunday = 7 - firstDay.GetDayOfWeek(); // Add 7 days to first sunday to get second sunday Int32 firstSunday = 1 + daysTillSunday; return day >= firstSunday; } else if (month == 10) { // October DST ends // Find last sunday of October Int32 lastDayNumber = DATECalc::DaysInMonth(month, IsLeapYear()); DATE lastDay(year, month, lastDayNumber); Int32 daysPastSunday = lastDay.GetDayOfWeek() % 7; Int32 lastSunday = lastDayNumber - daysPastSunday; return day < lastSunday; // > } else { return false; } } else { // Assume DST not implemented return false; } } // Description: Convert internal representation to Julian day number inline void DATE::InternalToJD() const { // Should only call this if currently in date representation mode assert(m_Date < 0); Int32 Year = GETCOMPONENT(m_Date, BITOFFSETYEAR, BITSIZEYEAR) + MINIMUMYEAR; Int32 Month = GETCOMPONENT(m_Date, BITOFFSETMONTH, BITSIZEMONTH); Int32 Day = GETCOMPONENT(m_Date, BITOFFSETDAY, BITSIZEDAY); m_Date = DATECalc::CalcJulianPeriod(Year, Month, Day); } // Description: Convert internal representation to date parts inline void DATE::InternalToDate() const { // Should only call this if currently in days representation mode assert(m_Date >= 0); // Convert to date parts DATECalc::DateS ConvDate; DATECalc::CalculateDate(m_Date, ConvDate); // Copy calculated values Int32 DateRep = ((ConvDate.m_Year - MINIMUMYEAR) << BITOFFSETYEAR) + ((ConvDate.m_WeekOfYear) << BITOFFSETWEEKOFYEAR) + ((ConvDate.m_Day) << BITOFFSETDAY) + ((ConvDate.m_DayOfWeek) << BITOFFSETDAYOFWEEK) + ((ConvDate.m_Month) << BITOFFSETMONTH) + ((ConvDate.m_YearForWeekOfYear - ConvDate.m_Year + 1) << BITOFFSETWEEKYEARDIF) + ((ConvDate.m_IsLeapYear) << BITOFFSETISLEAPYEAR) + (1 << 31); m_Date = DateRep; } <?php ob_start(); // global content ?> //> inline void FromString(@type& x, const char* text){ //SS x.FromString(text); x.FromStringYMD(text); } inline int ToString(const @type& x, char* text){ return x.ToString(text); } inline int64_t ClusterValue(const @type& x){ // correct it to Unix day return x.GetJulianDay(); } inline void ToJson(const @type& src, Json::Value & dest ) { char buffer[12]; src.ToString(buffer); dest = buffer; } inline void FromJson(const Json::Value & src, @type & dest ) { dest.FromStringYMD(src.asCString()); } // Hash function <?php $functions[] = ['Hash', ['@type'], 'BASE::BIGINT', true, true]; ?> template<> inline uint64_t Hash( const @type& val ) { return val.GetJulianDay(); } // Deep copy function inline void Copy( @type& to, const @type& from ) { to = from; } <?php $functions[] = ['IsNull', ['@type'], 'BASE::BOOL', true, true]; ?> inline bool IsNull( const @type & d ) { return d.IsNull(); } #ifdef _HAS_STD_HASH // C++11 STL-compliant hash struct specialization namespace std { template <> class hash<@type> { public: size_t operator () (const @type& key) const { return Hash(key); } }; } #endif // _HAS_STD_HASH <?php $globalContent = ob_get_clean(); ?> <?php return array('kind' => 'TYPE', "system_headers" => array("assert.h"), "user_headers" => array("datetimedefs.h", "datecalc.h", "Constants.h", "Config.h"), "complex" => false, 'binary_operators' => ['==', '!=', '>', '<', '>=', '<='], 'global_content' => $globalContent, 'constructors' => $constructors, 'methods' => $methods, 'functions' => $functions, 'properties' => ['clusterable'], 'describe_json' => DescribeJson('date', DescribeJsonStatic(['format' => 'YYYY/MM/DD'])), 'extras' => ['size.bytes' => 4]); }
function BASE64($t_args) { // The number of bytes encoded per string. $size = get_first_key($t_args, ['size', 0]); // The number of characters that should be used to encode each string. // Padding is acceptable but not necessarily, hence the acceptable number of // characters is an interval. $min = ceil($size * 4 / 3); $max = 4 * ceil($min / 4); $className = 'Base64_' . $size; $systemHeaders = ['cstring', 'cstdio']; $userHeaders = []; $libHeaders = ['base64.h']; $libraries = []; $constructors = []; $methods = []; $functions = []; $binaryOperators = []; $unaryOperators = []; $globalContent = ''; $complex = false; $properties = []; $extra = ['size.bytes' => 40]; $describeJson = DescribeJson('base64', DescribeJsonStatic(['size' => $size])); $globalContent = ''; ?> class <?php echo $className; ?> { public: // The number of bytes encoded. static const constexpr int kSize = <?php echo $size; ?> ; // The maximum number of characters that an input string is expected to have. static const constexpr int kMax = <?php echo $max; ?> ; // The minimum number of characters that an input string is expected to have. static const constexpr int kMin = <?php echo $min; ?> ; private: std::array<char, kSize> bytes; public: <?php $constructors[] = [[], true]; ?> <?php echo $className; ?> (); <?php $constructors[] = [['BASE::NULL'], true]; ?> <?php echo $className; ?> (const GrokitNull& nullval); <?php $constructors[] = [['BASE::STRING_LITERAL'], true]; ?> <?php echo $className; ?> (const char* str); <?php $binaryOperators[] = '=='; ?> bool operator ==(const <?php echo $className; ?> & other) const; <?php $binaryOperators[] = '!='; ?> bool operator !=(const <?php echo $className; ?> & other) const; void FromString(const char* str); int ToString(char* buffer) const; void FromJson(const Json::Value& src); void ToJson(Json::Value& src) const; }; inline <?php echo $className; ?> ::<?php echo $className; ?> () { bytes.fill(0); } <?php echo $className; ?> ::<?php echo $className; ?> (const GrokitNull& nullval) { bytes.fill(0); } inline <?php echo $className; ?> ::<?php echo $className; ?> (const char* str) { this->FromString(str); } inline bool <?php echo $className; ?> ::operator ==(const <?php echo $className; ?> & other) const { return std::memcmp(bytes.data(), other.bytes.data(), kSize); } inline bool <?php echo $className; ?> ::operator !=(const <?php echo $className; ?> & other) const { return !(*this == other); } inline void <?php echo $className; ?> ::FromString(const char* str) { size_t length = strlen(str); FATALIF(kMax < length || length < kMin,"Illegal base64-%d input: '%s'", kSize, str); std::string message = base64_decode(std::string(str)); std::memcpy(bytes.data(), message.data(), message.size()); } inline int <?php echo $className; ?> ::ToString(char* buffer) const { std::string encoded = base64_encode((unsigned char*) bytes.data(), kSize); return 1 + sprintf(buffer, "%s", encoded.c_str()); } inline void <?php echo $className; ?> ::FromJson(const Json::Value& src) { this->FromString(src.asCString()); } inline void <?php echo $className; ?> ::ToJson(Json::Value& dest) const { dest = base64_encode((unsigned char*) bytes.data(), kSize); } <?php ob_start(); ?> inline void FromString(@type& data, const char* buffer) { data.FromString(buffer); } inline int ToString(const @type& data, char* buffer) { return data.ToString(buffer); } inline void FromJson(const Json::Value& src, @type& dest) { dest.FromJson(src); } inline void ToJson(const @type& src, Json::Value& dest) { src.ToJson(dest); } <?php $globalContent .= ob_get_clean(); ?> <?php return ['kind' => 'TYPE', 'name' => $className, 'complex' => $complex, 'system_headers' => $systemHeaders, 'user_headers' => $userHeaders, 'lib_headers' => $libHeaders, 'libraries' => $libraries, 'binary_operators' => $binaryOperators, 'unary_operators' => $unaryOperators, 'global_content' => $globalContent, 'constructors' => $constructors, 'methods' => $methods, 'functions' => $functions, 'libraries' => $libraries, 'properties' => $properties, 'extras' => $extra, 'describe_json' => $describeJson]; }
function TIME() { $methods = []; $constructors = []; $functions = []; $bin_operators = []; $libraries = []; $system_headers = ['cinttypes', 'limits', 'string', 'stdio.h']; $system_headers[] = 'boost/date_time/posix_time/posix_time.hpp'; $libraries[] = 'boost_date_time'; $globalContent = ""; ?> class TIME { private: int32_t nMillis; static constexpr int32_t LEAP_START = 86399000; static constexpr int32_t MAX_TIME = 863999999; static constexpr int32_t INVALID_TIME = std::numeric_limits<int32_t>::min(); static constexpr int32_t SECONDS_TO_MILLIS = 1000; static constexpr int32_t MINUTES_TO_MILLIS = SECONDS_TO_MILLIS * 60; static constexpr int32_t HOURS_TO_MILLIS = MINUTES_TO_MILLIS * 60; static constexpr int32_t MILLIS_PER_SECOND = 1000; static constexpr int32_t SECONDS_PER_MINUTE = 60; static constexpr int32_t MINUTES_PER_HOUR = 60; static constexpr int32_t MillisFromFacets(const int32_t h, const int32_t m, const int32_t s, const int32_t ms); public: <?php $constructors[] = [[], true]; ?> constexpr TIME(void); <?php $constructors[] = [['BASE::INT'], true]; ?> constexpr TIME( const int32_t _millis ); <?php $constructors[] = [['BASE::NULL'], true]; ?> constexpr TIME( const GrokitNull & null ); <?php $constructors[] = [['BASE::INT', 'BASE::INT', 'BASE::INT', 'BASE::INT'], true]; ?> constexpr TIME( const int32_t hours, const int32_t minutes, const int32_t seconds, const int32_t millis ); <?php $methods[] = ['hour', [], 'BASE::BYTE', true]; ?> // Get the hours portion of the time constexpr int8_t hour(void) const; constexpr int8_t hours(void) const; <?php $methods[] = ['minute', [], 'BASE::BYTE', true]; ?> // Get the minutes portion of the time constexpr int8_t minute(void) const; constexpr int8_t minutes(void) const; <?php $methods[] = ['second', [], 'BASE::BYTE', true]; ?> // Get the seconds portion of the time constexpr int8_t second(void) const; constexpr int8_t seconds(void) const; <?php $methods[] = ['milli', [], 'BASE::SMALLINT', true]; ?> // Get the milliseconds portion of the time constexpr int16_t milli(void) const; constexpr int16_t millis(void) const; <?php $methods[] = ['as_hours', [], 'BASE::INT', true]; ?> // Get the time in hours since the beginning of the day constexpr int32_t as_hours(void) const; <?php $methods[] = ['as_minutes', [], 'BASE::INT', true]; ?> // Get the time in minutes since the beginning of the day constexpr int32_t as_minutes(void) const; <?php $methods[] = ['as_seconds', [], 'BASE::INT', true]; ?> // Get the time in seconds since the beginning of the day constexpr int32_t as_seconds(void) const; <?php $methods[] = ['as_millis', [], 'BASE::INT', true]; ?> // Get the time in milliseconds since the beginning of the day constexpr int32_t as_millis(void) const; constexpr bool is_valid(void) const; constexpr bool is_null(void) const; // Comparison operators <?php $bin_operators[] = '=='; ?> constexpr bool operator ==( const TIME & o ) const; <?php $bin_operators[] = '!='; ?> constexpr bool operator !=( const TIME & o ) const; <?php $bin_operators[] = '>'; ?> constexpr bool operator >( const TIME & o ) const; <?php $bin_operators[] = '<'; ?> constexpr bool operator <( const TIME & o ) const; //> <?php $bin_operators[] = '>='; ?> constexpr bool operator >=( const TIME & o ) const; <?php $bin_operators[] = '<='; ?> constexpr bool operator <=( const TIME & o ) const; //> // Addition and subtraction of time intervals <?php $bin_operators[] = '+'; ?> constexpr TIME operator +( const TIME & o ) const; <?php $bin_operators[] = '-'; ?> constexpr TIME operator -( const TIME & o ) const; void FromString( const char * str ); int ToString( char * buffer ) const; void FromJson( const Json::Value & ); void ToJson( Json::Value & ) const; }; inline constexpr int32_t TIME :: MillisFromFacets(const int32_t h, const int32_t m, const int32_t s, const int32_t ms) { return (h * HOURS_TO_MILLIS) + (m * MINUTES_TO_MILLIS) + (s * SECONDS_TO_MILLIS) + ms; } inline constexpr TIME :: TIME(void) : nMillis(INVALID_TIME) { } inline constexpr TIME :: TIME( const int32_t _millis ) : nMillis(_millis) { } inline constexpr TIME :: TIME( const int32_t h, const int32_t m, const int32_t s, const int32_t ms ) : nMillis(MillisFromFacets(h, m, s, ms)) { } inline constexpr int32_t TIME :: as_hours(void) const { return nMillis / HOURS_TO_MILLIS; } inline constexpr int8_t TIME :: hour(void) const { return as_hours(); } inline constexpr int8_t TIME :: hours(void) const { return hour(); } inline constexpr int32_t TIME :: as_minutes(void) const { return nMillis / MINUTES_TO_MILLIS; } inline constexpr int8_t TIME :: minute(void) const { return as_minutes() % MINUTES_PER_HOUR; } inline constexpr int8_t TIME :: minutes(void) const { return minute(); } inline constexpr int32_t TIME :: as_seconds(void) const { return nMillis / SECONDS_TO_MILLIS; } inline constexpr int8_t TIME :: second(void) const { return (LEAP_START > nMillis) ? as_seconds() % SECONDS_PER_MINUTE : 60; } inline constexpr int8_t TIME :: seconds(void) const { return second(); } inline constexpr int32_t TIME :: as_millis(void) const { return nMillis; } inline constexpr int16_t TIME :: milli(void) const { return as_millis() % MILLIS_PER_SECOND; } inline constexpr int16_t TIME :: millis(void) const { return milli(); } inline constexpr bool TIME :: is_valid(void) const { return nMillis >= 0 && MAX_TIME >= nMillis; } inline constexpr bool TIME :: is_null(void) const { return nMillis == INVALID_TIME; } inline constexpr bool TIME :: operator ==( const TIME & o ) const { return nMillis == o.nMillis; } inline constexpr bool TIME :: operator !=( const TIME & o ) const { return nMillis != o.nMillis; } inline constexpr bool TIME :: operator >( const TIME & o ) const { return nMillis > o.nMillis; } inline constexpr bool TIME :: operator <( const TIME & o ) const { //> return nMillis < o.nMillis; //> } inline constexpr bool TIME :: operator >=( const TIME & o ) const { return nMillis >= o.nMillis; } inline constexpr bool TIME :: operator <=( const TIME & o ) const { //> return nMillis <= o.nMillis; //> } inline constexpr TIME TIME :: operator +( const TIME & o ) const { return TIME(nMillis + o.nMillis); } inline constexpr TIME TIME :: operator -( const TIME & o ) const { return TIME(nMillis - o.nMillis); } inline void TIME :: FromString( const char * str ) { using namespace boost::posix_time; time_duration time = duration_from_string(std::string(str)); nMillis = time.total_milliseconds(); } inline int TIME :: ToString( char * buffer) const { using namespace boost::posix_time; // Constructs boost::time_duration around nMillis. Boost automatically // truncates the string if there are no fractional seconds. std::string output = to_simple_string(milliseconds(nMillis)).substr(0, 12); // Only the first 12 characters are kept, i.e. HH:MM:SS.mmm strcpy(buffer, output.substr(0, 12).c_str()); return 1 + output.length(); } inline void TIME :: FromJson( const Json::Value & src ) { this->FromString(src.asCString()); } inline void TIME :: ToJson( Json::Value & dest ) const { char buffer[9]; this->ToString(buffer); dest = buffer; } <?php ob_start(); ?> inline void FromString( @type & date, const char * buffer ) { date.FromString( buffer ); } inline int ToString( const @type & date, char * buffer ) { return date.ToString(buffer); } inline void FromJson( const Json::Value & src, @type & dest ) { dest.FromJson(src); } inline void ToJson( const @type & src, Json::Value & dest ) { src.ToJson(dest); } // Hash function <?php $functions[] = ['Hash', ['@type'], 'BASE::BIGINT', true, true]; ?> template<> inline uint64_t Hash( const @type& val ) { return val.as_millis(); } <?php $functions[] = ['IsNull', ['@type'], 'BASE::BOOL', true, true]; ?> inline bool IsNull( const @type & val ) { return val.is_null(); } #ifdef _HAS_STD_HASH <?php $system_headers[] = 'functional'; ?> // C++11 STL-compliant hash struct specialization namespace std { template <> class hash<@type> { public: size_t operator () (const @type& key) const { return Hash(key); } }; } #endif // _HAS_STD_HASH <?php $globalContent .= ob_get_clean(); ?> <?php return ['kind' => 'TYPE', 'system_headers' => $system_headers, 'libraries' => $libraries, 'user_headers' => ['Config.h'], 'binary_operators' => $bin_operators, 'global_content' => $globalContent, 'constructors' => $constructors, 'methods' => $methods, 'functions' => $functions, 'describe_json' => DescribeJson('time', DescribeJsonStatic(['format' => 'HH:mm:ss.SSS'])), 'extras' => ['size.bytes' => 4]]; }