/** * A fixed array containing a given type. * * This is very similar to the STL array datatype, except that the size is not * allowed to be 0. */ function FixedArray(array $t_args) { $constructors = []; $methods = []; $functions = []; $globalContent = ''; grokit_assert(array_key_exists('type', $t_args), 'FixedArray: No type given for elements'); grokit_assert(array_key_exists('size', $t_args), 'FixedArray: No size given'); $type = $t_args['type']; $size = $t_args['size']; if (is_array($type)) { // Perform type lookup $type = call_user_func_array('lookupType', $type); } else { $type = $type->lookup(); } grokit_assert(is_datatype($type), 'FixedArray: [type] argument must be a valid datatype'); grokit_assert($type->isFixedSize(), 'FixedArray: variable-sized types not supported'); grokit_assert(is_int($size), 'FixedArray: [size] argument must be an integer'); grokit_assert($size > 0, 'FixedArray: [size] arugment must be a positive number.'); $className = generate_name('FixedArray_' . $size . '_'); ?> struct <?php echo $className; ?> { using value_type = <?php echo $type; ?> ; using size_type = std::size_t; using difference_type = std::ptrdiff_t; using reference = value_type &; using const_reference = const value_type &; using pointer = value_type *; using const_pointer = const value_type *; using iterator = value_type *; using const_iterator = const value_type *; using reverse_iterator = std::reverse_iterator<iterator>; using const_reverse_iterator = std::reverse_iterator<const_iterator>; static constexpr const size_type SIZE = <?php echo $size; ?> ; value_type __elems_[SIZE > 0 ? SIZE : 1]; // No explicit contruct/copy/destroy for aggregate type <?php $constructors[] = [[], true]; ?> /***** Element Access *****/ <?php $methods[] = ['at', ['base::BIGINT'], $type->value(), true]; ?> reference at( size_type pos ) { if( size() <= pos ) { std::ostringstream ss; ss << "Element access out of range:" << " size=" << size() << " index=" << pos; throw std::out_of_range(ss.str()); } return __elems_[pos]; } const_reference at( size_type pos ) const { if( size() <= pos ) { std::ostringstream ss; ss << "Element access out of range:" << " size=" << size() << " index=" << pos; throw std::out_of_range(ss.str()); } return __elems_[pos]; } reference operator[]( size_type pos ) { return __elems_[pos]; } constexpr const_reference operator[]( size_type pos ) const { return __elems_[pos]; } <?php $methods[] = ['front', [], $type->value(), true]; ?> reference front() { return __elems_[0]; } constexpr const_reference front() const { return __elems_[0]; } <?php $methods[] = ['back', [], $type->value(), true]; ?> reference back() { return __elems_[SIZE-1]; } constexpr const_reference back() const { return __elems_[SIZE-1]; } pointer data() noexcept { return __elems_; } const_pointer data() const noexcept { return __elems_; } /***** Iterators *****/ iterator begin() noexcept { return __elems_; } const_iterator cbegin() const noexcept { return __elems_; } const_iterator begin() const noexcept { return cbegin(); } iterator end() noexcept { return __elems_ + size(); } const_iterator cend() const noexcept { return __elems_ + size(); } const_iterator end() const noexcept { return cend(); } reverse_iterator rbegin() noexcept { return reverse_iterator(end()); } const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(cend()); } const_reverse_iterator rbegin() const noexcept { return crbegin(); } reverse_iterator rend() noexcept { return reverse_iterator(begin()); } const_reverse_iterator crend() const noexcept { return const_reverse_iterator(cbegin()); } const_reverse_iterator rend() const noexcept { return crend(); } /***** Capacity *****/ <?php $methods[] = ['empty', [], 'base::bool', true]; ?> constexpr bool empty() const noexcept { return SIZE == 0; } <?php $methods[] = ['size', [], 'base::BIGINT', true]; ?> constexpr size_type size() const noexcept { return SIZE; } constexpr size_type max_size() const noexcept { return SIZE; } /***** Operations *****/ void fill( const value_type & value ) { std::fill_n(begin(), SIZE, value); } void swap( <?php echo $className; ?> & other ) noexcept(noexcept(std::swap(std::declval<value_type&>(), std::declval<value_type&>()))) { std::swap( __elems_, other.__elems_ ); } /***** EXTENTIONS *****/ void from_memory( const_pointer mem ) { std::copy(mem, mem+SIZE, __elems_); } }; <?php ob_start(); ?> inline bool operator == ( const @type & lhs, const @type & rhs ) { for( @type::size_type i = 0; i < @type::SIZE; i++ ) { //> if( lhs[i] != rhs[i] ) return false; } return true; } inline bool operator != ( const @type & lhs, const @type & rhs ) { for( @type::size_type i = 0; i < @type::SIZE; i++ ) { //> if( lhs[i] != rhs[i] ) return true; } return false; } inline bool operator < ( const @type & lhs, const @type & rhs ) { //> return std::lexicographical_compare(lhs.cbegin(), lhs.cend(), rhs.cbegin(), rhs.cend()); } inline bool operator > ( const @type & lhs, const @type & rhs ) { return rhs < lhs; //> } inline bool operator <= ( const @type & lhs, const @type & rhs ) { //> return !(lhs > rhs); } inline bool operator >=( const @type & lhs, const @type & rhs ) { return !(lhs < rhs); //> } // ostream operator for easier debugging. template<class CharT, class Traits = std::char_traits<CharT>> std::basic_ostream<CharT, Traits>& operator << ( std::basic_ostream<CharT, Traits> & os, const @type s ) { std::ostringstream ss; bool first = true; ss << "["; for( const auto & elem : s ) { if( first ) { first = false; } else { ss << ", "; } ss << elem; } ss << "]"; os << ss.str(); return os; } inline void ToJson( const @type & src, Json::Value & dest ) { dest = Json::Value(Json::arrayValue); for( @type::const_reference elem : src ) { Json::Value tmp; ToJson( elem, tmp ); dest.append(tmp); } } inline void FromJson( const Json::Value & src, @type & dest ) { FATALIF(!src.isArray(), "Attempted to read array from non-array JSON"); FATALIF(!(src.size() == @type::SIZE), "Invalid number of elements in JSON for Array"); for( Json::ArrayIndex i = 0; i < @type::SIZE; i++ ) { //> FromJson( src[i], dest[i] ); } } inline int ToString( const @type & x, char * buffer ) { <?php if ($size > 0) { ?> char * start = buffer; char * current = start; for( const auto & val : x ) { current += ToString( val, current ); // Replace null with space *(current-1) = ' '; } // Replace final comma with null *(current-1) = '\0'; return current - start; <?php } else { // if size > 0 ?> buffer[0] = '\0'; return 1; <?php } // if size == 0 ?> } inline void FromString( @type & x, const char * buffer ) { char * current = NULL; char * saveptr = NULL; const char * delim = " "; char * copy = strdup(buffer); current = strtok_r(copy, delim, &saveptr); for( auto & val : x ) { FATALIF(current == NULL, "Not enough elements in string representation of array"); ToString(val, current); current = strtok_r(NULL, delim, &saveptr); } free((void *) copy); } <?php $functions[] = ['Hash', ['@type'], 'BASE::BIGINT', true, true]; ?> template<> inline uint64_t Hash( const @type & val ) { uint64_t hashVal = H_b; for( @type::const_reference elem : val ) { hashVal = CongruentHash(Hash(elem), hashVal); } return hashVal; } namespace std { #ifdef _HAS_STD_HASH // C++11 STL-compliant hash struct specialization template <> class hash<@type> { public: size_t operator () (const @type& key) const { return Hash(key); } }; #endif // _HAS_STD_HASH // std::get specializations template< size_t I > constexpr @type::reference get( @type& a ) { static_assert(I < @type::SIZE, "Index out of bounds for std::get(@type)"); return a.__elems_[I]; } template< size_t I > constexpr @type::value_type&& get( @type&& a ) { static_assert(I < @type::SIZE, "Index out of bounds for std::get(@type)"); return std::move(a.__elems_[I]); } template< size_t I > constexpr @type::const_reference get( const @type& a ) { static_assert(I < @type::SIZE, "Index out of bounds for std::get(@type)"); return a.__elems_[I]; } // std::swap specializations inline void swap( @type& lhs, @type& rhs ) { lhs.swap(rhs); } // std::tuple_size template<> class tuple_size< @type > : public integral_constant<size_t, @type::SIZE> { }; // std::tuple_element template<size_t I> struct tuple_element< I, @type > { using type = @type::value_type; }; } <?php $globalContent .= ob_get_clean(); ?> <?php $innerDesc = function ($var, $myType) use($type) { $describer = $type->describer('json'); ?> <?php echo $var; ?> ["size"] = Json::Int64(<?php echo $myType; ?> ::SIZE); <?php $innerVar = "{$var}[\"inner_type\"]"; $describer($innerVar, $type); }; $sys_headers = ['iterator', 'algorithm', 'stdexcept', 'utility', 'cinttypes', 'cstddef', 'iostream', 'sstream', 'cstring', 'cstdlib']; $user_headers = ['Config.h']; $extras = ['size' => $size, 'type' => $type]; if ($type->has('size.bytes')) { $extras['size.bytes'] = $size * $type->get('size.bytes'); } return ['kind' => 'TYPE', 'name' => $className, 'system_headers' => $sys_headers, 'user_headers' => $user_headers, 'constructors' => $constructors, 'methods' => $methods, 'functions' => $functions, 'binary_operators' => ['==', '!=', '<', '>', '<=', '>='], 'global_content' => $globalContent, 'complex' => false, 'properties' => ['container', 'sequence', 'array'], 'extras' => $extras, 'describe_json' => DescribeJson('array', $innerDesc)]; }
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 POSIXTIME() { $systemHeaders = ['cstdio']; $userHeaders = ['Config.h']; $libHeaders = []; $libraries = []; $constructors = []; $methods = []; $functions = []; $binaryOperators = []; $unaryOperators = []; $globalContent = ''; $complex = false; $properties = ['clusterable']; $extra = ['size.bytes' => 8]; $describeJson = DescribeJson('posixtime'); $systemHeaders[] = 'boost/date_time/posix_time/posix_time.hpp'; $systemHeaders[] = 'boost/date_time/gregorian/gregorian.hpp'; $systemHeaders[] = 'boost/date_time/dst_rules.hpp'; $systemHeaders[] = 'boost/date_time/local_time_adjustor.hpp'; $systemHeaders[] = 'boost/date_time/c_local_time_adjustor.hpp'; $libraries[] = 'boost_date_time'; $globalContent = ''; ?> using namespace boost::posix_time; using namespace boost::gregorian; class POSIXTIME { private: boost::posix_time::ptime time; public: <?php $constructors[] = [[], true]; ?> POSIXTIME(); <?php $constructors[] = [['BASE::Null'], true]; ?> POSIXTIME(const GrokitNull& null); <?php $constructors[] = [['BASE::INT'], true]; ?> POSIXTIME(int seconds); <?php $constructors[] = [['BASE::BIGINT'], true]; ?> POSIXTIME(long useconds); POSIXTIME(const boost::posix_time::ptime& time); <?php $binaryOperators[] = '=='; ?> bool operator ==(const POSIXTIME& other) const; <?php $binaryOperators[] = '!='; ?> bool operator !=(const POSIXTIME& other) const; <?php $binaryOperators[] = '<'; ?> bool operator <(const POSIXTIME& other) const; <?php $binaryOperators[] = '>'; ?> bool operator >(const POSIXTIME& other) const; <?php $binaryOperators[] = '<='; ?> bool operator <=(const POSIXTIME& other) const; <?php $binaryOperators[] = '>='; ?> bool operator >=(const POSIXTIME& other) const; void FromString(const char* buffer); int ToString(char* buffer) const; void FromJson(const Json::Value& src); void ToJson(Json::Value& src) const; }; inline POSIXTIME::POSIXTIME() : time(ptime(not_a_date_time)) { } inline POSIXTIME::POSIXTIME(const GrokitNull& null) : time(ptime(not_a_date_time)) { } inline POSIXTIME::POSIXTIME(int seconds) : time(from_time_t(seconds)) { } inline POSIXTIME::POSIXTIME(long useconds) : time(ptime(date(1970, 1, 1), microseconds(useconds))) { } inline POSIXTIME::POSIXTIME(const boost::posix_time::ptime& time) : time(time) { } inline bool POSIXTIME::operator ==(const POSIXTIME& other) const { return this->time == other.time; } inline bool POSIXTIME::operator !=(const POSIXTIME& other) const { return this->time != other.time; } inline bool POSIXTIME::operator <(const POSIXTIME& other) const { return this->time < other.time; } inline bool POSIXTIME::operator >(const POSIXTIME&other) const { return this->time > other.time; } inline bool POSIXTIME::operator <=(const POSIXTIME& other) const { return this->time <= other.time; } inline bool POSIXTIME::operator >=(const POSIXTIME& other) const { return this->time >= other.time; } inline void POSIXTIME::FromString(const char* str) { using namespace boost::posix_time; using namespace boost::gregorian; time = ptime(date(1970, 1, 1), milliseconds(atol(str))); } inline int POSIXTIME::ToString(char* buffer) const { using namespace boost::posix_time; using namespace boost::gregorian; auto diff = time - ptime(date(1970, 1, 1)); return 1 + sprintf(buffer, "%li", diff.total_milliseconds()); } inline void POSIXTIME::FromJson(const Json::Value& src) { using namespace boost::posix_time; using namespace boost::gregorian; time = ptime(date(1970, 1, 1), milliseconds(src.asInt64())); } inline void POSIXTIME::ToJson(Json::Value& dest) const { using namespace boost::posix_time; using namespace boost::gregorian; auto diff = time - ptime(date(1970, 1, 1)); dest = (Json::Int64) diff.total_milliseconds(); } <?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', '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 UUID() { $systemHeaders = []; $userHeaders = []; $libHeaders = []; $libraries = []; $constructors = []; $methods = []; $functions = []; $binaryOperators = ['==', '!=', '>', '<', '>=', '<=']; $unaryOperators = []; $globalContent = ''; $complex = false; $properties = ['_primative_']; $extra = ['size.bytes' => 16]; $describeJson = DescribeJson('uuid'); $systemHeaders[] = 'boost/uuid/uuid.hpp'; $systemHeaders[] = 'boost/uuid/uuid_generators.hpp'; $systemHeaders[] = 'boost/uuid/string_generator.hpp'; $systemHeaders[] = 'boost/lexical_cast.hpp'; $systemHeaders[] = 'boost/uuid/uuid_io.hpp'; $globalContent = ''; ?> using UUID = boost::uuids::uuid; <?php $constructors[] = [['BASE::NULL'], true, 'UUID_Null']; ?> inline UUID UUID_Null(const GrokitNull& null) { boost::uuids::nil_generator gen; return gen(); } <?php ob_start(); ?> inline void FromString(@type& uuid, const char* buffer) { boost::uuids::string_generator converter; uuid = converter(std::string(buffer)); } inline int ToString(const @type& uuid, char* buffer) { const std::string tmp = boost::lexical_cast<std::string>(uuid); return 1 + sprintf(buffer, "%s", tmp.c_str()); } inline void FromJson(const Json::Value& src, @type& dest) { FromString(dest, src.asCString()); } inline void ToJson(const @type& src, Json::Value& dest) { dest = boost::lexical_cast<std::string>(src); } <?php $globalContent .= ob_get_clean(); ?> <?php return ['kind' => 'TYPE', '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 IPV4ADDR() { $constructors = []; $methods = []; $functions = []; $globalContent = ""; ?> /** This type implements an efficient IP v4 address Internal representation is an int (for efficiency). */ class IPv4; bool operator < (const IPv4 &d1, const IPv4 &d2); bool operator <= (const IPv4 &d1, const IPv4 &d2); bool operator > (const IPv4 &d1, const IPv4 &d2); bool operator >= (const IPv4 &d1, const IPv4 &d2); bool operator == (const IPv4 &d1, const IPv4 &d2); bool operator != (const IPv4 &d1, const IPv4 &d2); // function to extract the domain (class C) IPv4 Domain(IPv4 x); class IPv4 { private: union addr_rep { unsigned int asInt; struct { unsigned char c1; unsigned char c2; unsigned char c3; unsigned char c4; } split; }; addr_rep addr; public: <?php $constructors[] = [[], true]; ?> // Default constructor IPv4(void){ addr.asInt = 0; } <?php $constructors[] = [['BASE::STRING_LITERAL'], true]; ?> /* Constructor from string "xxx.xxx.xxx.xxx". The format is fixed */ IPv4 (const char *_addr){ FromString(_addr); } // constructor from integers <?php $constructors[] = [['BASE::BYTE', 'BASE::BYTE', 'BASE::BYTE', 'BASE::BYTE'], true]; ?> IPv4(char c1, char c2, char c3, char c4){ addr.split.c1 = c1; addr.split.c2 = c2; addr.split.c3 = c3; addr.split.c4 = c4; } <?php $constructors[] = [['BASE::NULL'], true]; ?> IPv4( const GrokitNull & nullval ) { addr.asInt = 0; } void FromString(const char *_addr) { unsigned int c1; unsigned int c2; unsigned int c3; unsigned int c4; sscanf(_addr, "%u.%u.%u.%u", &c1, &c2, &c3, &c4); addr.split.c1 = c1; addr.split.c2 = c2; addr.split.c3 = c3; addr.split.c4 = c4; } int ToString(char* text) const{ return 1+sprintf(text,"%u.%u.%u.%u", (unsigned int) addr.split.c1, (unsigned int) addr.split.c2, (unsigned int) addr.split.c3, (unsigned int) addr.split.c4); } void Print(void){ printf("%u.%u.%u.%u", (unsigned int) addr.split.c1, (unsigned int) addr.split.c2, (unsigned int) addr.split.c3, (unsigned int) addr.split.c4); } <?php $methods[] = ['IsValid', [], 'BASE::BOOL', true]; ?> bool IsValid(void) const { return addr.asInt != 0; } <?php $methods[] = ['IsNull', [], 'BASE::BOOL', true]; ?> bool IsNull(void) const { return addr.asInt == 0; } uint32_t asInt(void) const { return addr.asInt; } /* operators */ friend bool operator < (const IPv4 &d1, const IPv4 &d2) { return (d1.addr.asInt<d2.addr.asInt); } friend bool operator <= (const IPv4 &d1, const IPv4 &d2) { return (d1.addr.asInt<=d2.addr.asInt); } friend bool operator > (const IPv4 &d1, const IPv4 &d2) { return (d1.addr.asInt>d2.addr.asInt); } friend bool operator >= (const IPv4 &d1, const IPv4 &d2) { return (d1.addr.asInt>=d2.addr.asInt); } friend bool operator == (const IPv4 &d1, const IPv4 &d2) { return (d1.addr.asInt==d2.addr.asInt); } friend bool operator != (const IPv4 &d1, const IPv4 &d2) { return (d1.addr.asInt!=d2.addr.asInt); } IPv4& operator =( const IPv4& other ) { addr.asInt = other.addr.asInt; return *this; } <?php $functions[] = ['Domain', ['@type'], '@type', true]; ?> friend IPv4 Domain(IPv4 x){ IPv4 rez=x; rez.addr.split.c4=0; return rez; } static bool Between (const IPv4 &d, const IPv4 &dl, const IPv4 &dr) { return (d.addr.asInt >= dl.addr.asInt && d.addr.asInt <= dr.addr.asInt); //> } }; // compatibility with the other type definitions typedef IPv4 IPV4ADDR; <?php ob_start(); ?> inline void FromString( @type & x, const char* text){ x.FromString(text); } inline int ToString(const @type& x, char* text){ return x.ToString(text); } inline void ToJson( const @type & x, Json::Value & dest ) { char buffer[20]; ToString(x, buffer); dest = buffer; } inline void FromJson( const Json::Value & src, @type & dest ) { FromString(dest, src.asCString()); } // hash function, just return the unsigned int inside <?php $functions[] = ['Hash', ['@type'], 'BASE::BIGINT', true, true]; ?> template<> inline uint64_t Hash(const @type & d){ return d.asInt(); } // Deep copy inline void Copy( @type& to, const @type& from ) { to = from; } #ifdef _HAS_STD_HASH #include <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 $functions[] = ['IsNull', ['@type'], 'BASE::BOOL', true, true]; ?> inline bool IsNull( const @type & d ) { return d.IsNull(); } <?php $globalContent .= ob_get_clean(); ?> <?php return array('kind' => 'TYPE', 'constructors' => $constructors, 'methods' => $methods, 'functions' => $functions, 'global_content' => $globalContent, "user_headers" => array("Config.h"), "system_headers" => array("stdlib.h", "stdio.h"), "complex" => false, 'binary_operators' => ['==', '!=', '>', '<', '>=', '<='], 'describe_json' => DescribeJson('ipv4addr'), 'extras' => ['size.bytes' => 4]); }
function JSON(array $t_args) { $debug = get_default($t_args, 'debug', 0); ?> class JSON { public: typedef Json::Value inner_type; private: // pointer to inner_type object inner_type* data; public: // constructor from Json::value; steals the content so call it only when done JSON(inner_type& _data); JSON & operator =(inner_type& data); // default constructor JSON(void):data(new inner_type){}; // methods to access object const inner_type& get(void) const{ return *data; } // set steals the content void set(inner_type& obj); void FromString(const char* text); int ToString(char* text) const; void fromJson( const Json::Value & src ); void toJson( Json::Value & dest ) const; uint64_t GetId(void) const { return reinterpret_cast<uint64_t>(data); } void copy(const JSON& other){ (*data) = *(other.data); } void Destroy(void); ~JSON(void){ } }; inline JSON :: JSON(inner_type& _data){ // create new internal value and steal the content of the argument data = new inner_type; data->swap(_data); } inline JSON & JSON :: operator = (inner_type & data) { set(data); return *this; } inline void JSON :: set(inner_type& obj) { data = new inner_type; data->swap(obj); } inline void JSON :: FromString(const char* text){ std::stringstream st(text); Json::Reader rd; rd.parse(st, *data, false); } inline int JSON :: ToString(char* text) const { Json::FastWriter fw; std::string str = fw.write(*data); strcpy(text, str.c_str()); size_t size = str.size(); // FastWriter adds a newline to the end of the text. Remove it. text[size] = '\0'; return size; } inline void JSON :: fromJson( const Json::Value & src ) { if( data == nullptr ) { data = new inner_type; } *data = src; } inline void JSON :: toJson( Json::Value & dest ) const { if( data != nullptr ) dest = *data; } inline void JSON :: Destroy(void) { if (data) delete data; data = nullptr; } <?php ob_start(); ?> inline void FromString(@type & x, const char* text){ x.FromString(text); } inline int ToString(const @type & x, char* text){ return x.ToString(text); } inline void ToJson( const @type & src, Json::Value & dest ) { src.toJson(dest); } inline void FromJson( const Json::Value & src, @type & dest ) { dest.fromJson(src); } // The hash function // we just use conversion to unsigned int template<> inline uint64_t Hash(const @type& x){ return x.GetId();} // Deep copy inline void Copy( @type & to, const @type & from ) { to.copy(from); } <?php $gContent = ob_get_clean(); ?> <?php return array('kind' => 'TYPE', "system_headers" => array("string", "sstream", "inttypes.h", 'jsoncpp/json/json.h'), 'libraries' => ['jsoncpp'], "complex" => false, "global_content" => $gContent, 'properties' => [], 'destroy' => true, 'describe_json' => DescribeJson('json')); }
function DOUBLE() { // global content $gContent = ""; $functions = []; $constructors = []; ?> typedef double DOUBLE; // use native double ///////////////// // Aliases // NO ALIASES ////////////// // Inline functions <?php $constructors[] = [['BASE::NULL'], true, 'DOUBLE_Null']; ?> inline DOUBLE DOUBLE_Null( const GrokitNull & n ) { return std::numeric_limits<DOUBLE>::quiet_NaN(); } <?php ob_start(); ?> inline void FromString(@type & x, const char* text){ x = std::strtod(text, nullptr); } inline int ToString(const @type & x, char* text){ // add 1 for the \0 return 1+sprintf(text,"%1.15g", x); } // the hash function // reinterpret bits as 64 bit int template<> inline uint64_t Hash( const @type& val){ return *((const uint64_t*)(&val)); } // Deep copy inline void Copy( @type & to, const @type & from ) { to = from; } <?php $functions[] = ['IsNull', ['@type'], 'BASE::BOOL', true, true]; ?> inline bool IsNull( @type f ) { return isnan(f); } <?php $gContent .= ob_get_clean(); ?> ////////////// // Operators // all operators defined by C++ <?php return array('kind' => 'TYPE', "system_headers" => array("cstdlib", "cstdio", "cinttypes", 'cmath'), "complex" => false, "global_content" => $gContent, 'binary_operators' => ['+', '-', '*', '/', '==', '!=', '>', '<', '>=', '<='], 'unary_operators' => ['+', '-'], 'constructors' => $constructors, 'functions' => $functions, 'properties' => ['real', 'numeric', '_primative_'], 'describe_json' => DescribeJson('float'), 'extras' => ['size.bytes' => 8]); }
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 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 FACTOR(array $t_args) { $rawDict = get_first_key($t_args, ['dictionary', 'dict', 0]); // Double the quotes so that we escape them in SQLite, and add backslashes // to them so that we escape them in C++. $dict = addcslashes(\grokit\doubleChars($rawDict, '"'), '"\\'); $cardinality = \grokit\dictionarySize($rawDict); $storageBytes = get_first_key_default($t_args, ['bytes', 1], 2); $cardBytes = $cardinality > 0 ? intval(ceil(log($cardinality, 256))) : 1; $storageBytes = $cardBytes > $storageBytes ? $cardBytes : $storageBytes; switch ($storageBytes) { case 1: $storageType = 'uint8_t'; break; case 2: $storageType = 'uint16_t'; break; case 4: $storageType = 'uint32_t'; break; case 8: $storageType = 'uint64_t'; break; default: grokit_error('Unsupported # of bytes (' . $storageBytes . ') given for FACTOR, only 1, 2, 4, and 8 supported.'); } $className = generate_name('FACTOR_' . ensure_identifier($dict)); $stringType = lookupType('base::STRING'); $globalContent = ''; $methods = []; $constructors = []; $functions = []; ?> class <?php echo $className; ?> { public: typedef <?php echo $storageType; ?> StorageType; static const char * DictionaryName __attribute__((weak)); static const StorageType InvalidID __attribute__((weak)); static const StorageType MaxID __attribute__((weak)); static const Dictionary & globalDictionary __attribute__((weak)); public: /* ----- Members ----- */ // The ID of this Factor; StorageType myID; /* ----- Constructors / Destructors ----- */ // Default constructor <?php echo $className; ?> ( void ); // Constructor from null (same as default) <?php echo $className; ?> ( const GrokitNull & ); // Constructor from C strings / string literals <?php $constructors[] = [['base::STRING_LITERAL'], true]; ?> <?php echo $className; ?> ( const char * ); // Constructor from Grokit STRING type. <?php $constructors[] = [['base::STRING'], true]; ?> <?php echo $className; ?> ( const <?php echo $stringType; ?> & ); // Constructor from storage type <?php echo $className; ?> ( const StorageType ); // Copy constructor and copy assignment // These can both be default <?php echo $className; ?> ( const <?php echo $className; ?> & ) = default; <?php echo $className; ?> & operator =( const <?php echo $className; ?> & ) = default; // Destructor ~<?php echo $className; ?> () { } /* ----- Methods ----- */ // Standard FromString method void FromString( const char * ); // FromString method used when building the dictionaries. void FromString( const char *, Dictionary & ); // Looks up the factor in the global dictionary and returns the string <?php $methods[] = ['ToString', [], 'base::STRING_LITERAL', true]; ?> const char * ToString( void ) const; // Returns the ID of the Factor. StorageType GetID( void ) const; // Returns whether or not the Factor is valid. <?php $methods[] = ['Valid', [], 'base::bool', true]; ?> bool Valid( void ) const; <?php $methods[] = ['Invalid', [], 'base::bool', true]; ?> bool Invalid( void ) const; // Translate the content void Translate( const Dictionary::TranslationTable& ); void toJson( Json::Value & dest ) const; void fromJson( const Json::Value & src ); /* ----- Operators ----- */ // The dictionary keeps track of what the sorted order of the strings is. // These methods are based on the lexicographical ordering of the strings // the factors represent 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 StorageType () const; }; // Static member initialization const <?php echo $className; ?> ::StorageType <?php echo $className; ?> ::InvalidID = std::numeric_limits<StorageType>::max(); const <?php echo $className; ?> ::StorageType <?php echo $className; ?> ::MaxID = <?php echo $className; ?> ::InvalidID - 1; const char * <?php echo $className; ?> ::DictionaryName = "<?php echo $dict; ?> "; const Dictionary & <?php echo $className; ?> ::globalDictionary = Dictionary::GetDictionary(<?php echo $className; ?> ::DictionaryName); /* ----- Constructors ----- */ // Default constructor inline <?php echo $className; ?> :: <?php echo $className; ?> ( void ): myID(InvalidID) {} inline <?php echo $className; ?> :: <?php echo $className; ?> ( const GrokitNull & nullval ): myID(InvalidID) { } // Constructor from C strings / string literals inline <?php echo $className; ?> :: <?php echo $className; ?> ( const char * str ) { FromString(str); } // Constructor from Grokit STRING type inline <?php echo $className; ?> :: <?php echo $className; ?> ( const <?php echo $stringType; ?> & str ) { FromString(str.ToString()); } // Constructor from storage type inline <?php echo $className; ?> :: <?php echo $className; ?> ( const <?php echo $storageType; ?> id ): myID(id) { } /* ----- Methods ----- */ inline auto <?php echo $className; ?> :: GetID(void) const -> StorageType { return myID; } // Standard FromString method inline void <?php echo $className; ?> :: FromString( const char * str ) { // Global dictionary will return InvalidID if not found myID = globalDictionary.Lookup(str, InvalidID ); } // FromString method used when building the dictionaries inline void <?php echo $className; ?> :: FromString( const char * str, Dictionary & localDict ) { // First check if we are in the local dictionary myID = localDict.Lookup(str, InvalidID ); if( myID != InvalidID ) return; // Next check if we are in the global dictionary myID = globalDictionary.Lookup(str, InvalidID ); if( myID != InvalidID ) return; // Add a new entry to the local dictionary. // The dictionary should throw an error if the new ID is greater than // MaxID. myID = localDict.Insert( str, MaxID ); } // Looks up the factor in the global dictionary and returns the string inline const char * <?php echo $className; ?> :: ToString( void ) const { return globalDictionary.Dereference(myID); } // Determine whether or not the factor is valid inline bool <?php echo $className; ?> :: Valid( void ) const { return myID != InvalidID; } inline bool <?php echo $className; ?> :: Invalid(void) const { return myID == InvalidID; } // Translate the content inline void <?php echo $className; ?> :: Translate( const Dictionary::TranslationTable & tbl ) { auto it = tbl.find(myID); if( it != tbl.end() ) { myID = it->second; } } 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(); } /* ----- Operators ----- */ inline bool <?php echo $className; ?> :: operator ==( const <?php echo $className; ?> & o ) const { return myID == o.myID; } inline bool <?php echo $className; ?> :: operator !=( const <?php echo $className; ?> & o ) const { return myID != o.myID; } inline bool <?php echo $className; ?> :: operator <( const <?php echo $className; ?> & o ) const { return Valid() && o.Valid() && globalDictionary.Compare(myID, o.myID) < 0; } inline bool <?php echo $className; ?> :: operator <=( const <?php echo $className; ?> & o ) const { return Valid() && o.Valid() && globalDictionary.Compare(myID, o.myID) <= 0; } inline bool <?php echo $className; ?> :: operator >( const <?php echo $className; ?> & o ) const { return Valid() && o.Valid() && globalDictionary.Compare(myID, o.myID) > 0; } inline bool <?php echo $className; ?> :: operator >=( const <?php echo $className; ?> & o ) const { return Valid() && o.Valid() && globalDictionary.Compare(myID, o.myID) >= 0; } // Implicit conversion to storage type inline <?php echo $className; ?> :: operator StorageType() const { return myID; } <?php ob_start(); // Global functions ?> inline void FromString( @type & f, const char * str ) { f.FromString(str); } inline void FromString( @type & f, const char * str, Dictionary & localDict ) { f.FromString(str, localDict); } inline int ToString( const @type & f, char * buffer ) { const char * str = f.ToString(); strcpy(buffer, str); return strlen(buffer) + 1; } <?php $functions[] = ['Hash', ['@type'], 'base::BIGINT', true, true]; ?> template<> inline uint64_t Hash( const @type & x ) { return x.GetID(); } 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 f ) { return f.Invalid(); } <?php $globalContent .= ob_get_clean(); ?> <?php // Function to get the dictionary at runtime. $describeInfoJson = function ($var, $myType) { ?> <?php echo $var; ?> ["levels"] = Json::Value(Json::arrayValue); for( auto it = <?php echo $myType; ?> ::globalDictionary.cbegin(); it != <?php echo $myType; ?> ::globalDictionary.cend(); it++ ) { <?php echo $var; ?> ["levels"][it->first] = it->second; } <?php }; return ['kind' => 'TYPE', 'name' => $className, 'dictionary' => $dict, 'system_headers' => ['limits', 'cstring', 'cinttypes'], 'user_headers' => ['Dictionary.h', 'DictionaryManager.h', 'ColumnIteratorDict.h'], 'properties' => ['categorical'], 'extras' => ['cardinality' => $cardinality, 'size.bytes' => $storageBytes], 'binary_operators' => ['==', '!=', '<', '>', '<=', '>='], 'global_content' => $globalContent, 'complex' => 'ColumnIteratorDict< @type >', 'methods' => $methods, 'constructors' => $constructors, 'functions' => $functions, 'describe_json' => DescribeJson('factor', $describeInfoJson)]; }
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 STRING(array $t_args) { $debug = get_default($t_args, 'debug', 0); $deepCon = get_default($t_args, 'construct.deep', true); $deepAssign = get_default($t_args, 'assign.deep', false); // global content $gContent = ""; $className = \count($t_args) > 0 ? generate_name("STRING") : "STRING"; $constructors = []; $methods = []; $functions = []; ?> class <?php echo $className; ?> { public: // the type used for the size typedef size_t SizeType; private: // The length of the string SizeType length; // The null-terminated string const char * str; // Whether or not the string is responsible for its own storage. bool localStorage; ///// Private Functions ///// // Clears the value of the string, deallocating memory if necessary. void Clear(); public: // The maximum length for a string in the system. static const SizeType MaxObjectLength = 1024; static const SizeType HeaderLength = 1024; // Use the DELETE character as the NULL, since 0 is end of string. // We'll use 0xFF as the null character because it is not a valid // character in UTF-8 static const char NULL_CHAR = 0xFF; // Statically allocate the null string. static const char NULL_STR[2] __attribute__((weak)); // Empty string <?php echo $className; ?> (); <?php echo $className; ?> ( <?php echo $className; ?> && ); // Construct a NULL string <?php $constructors[] = [['BASE::NULL'], true]; ?> <?php echo $className; ?> ( const GrokitNull & n ); // Construct the object on top of the given null terminated string. <?php $constructors[] = [['base::STRING_LITERAL'], true]; ?> <?php echo $className; ?> ( const char * _str ); // Create string from at most n characters in the given string <?php echo $className; ?> ( const char *_str, size_t n ); // Create string from STL string <?php echo $className; ?> ( const std::string & str ); // Make a copy of the other string (deep) <?php echo $className; ?> ( const <?php echo $className; ?> & other ); // Copy assigment operator (shallow) <?php echo $className; ?> & operator = ( const <?php echo $className; ?> & other ); // Destructor ~<?php echo $className; ?> (); ///// Serialization / Deserialization operations ///// // Serialize myself to the buffer. char * Serialize( char * buffer ) const; void * Serialize( void * buffer ) const; // Deserialize myself from the buffer void Deserialize( const char * buffer ); // Return the size (in bytes) this object writes in Serialize and reads in Deserialize. int GetObjLength() const; SizeType GetSize() const; ///// Utilities ///// // Copy the data from the other string into this one (deep copy) void Copy( const <?php echo $className; ?> & other ); void Copy( const char * str ); ///// General Methods ///// // Return the length of the string <?php $methods[] = ['Length', [], 'base::INT', true]; ?> SizeType Length( void ) const; <?php $methods[] = ['CharAt', ['base::INT'], ['base::BYTE'], true]; ?> unsigned char CharAt( int i ) const; <?php $methods[] = ['IsNull', [], ['BASE::BOOL'], true]; ?> bool IsNull(void) const; // Return the null-terminated string the object represents const char * ToString( void ) const; void toJson( Json::Value & dest ) const; void fromJson( const Json::Value & src ); // Operators // Access characters in the string. // Performs no bounds checking const char & operator [] ( SizeType index ) const; // Read a character at the specified index in the string. // Performs index sanity checking. const char & at( SizeType index ) const; <?php if ($debug > 0) { ?> // DEBUGGING std::string DebugString(void) const { std::ostringstream ostream; ostream << "Length: " << length << " local: " << localStorage << " str: " << std::string(str); return ostream.str(); //> } <?php } // if debug > 0 ?> }; const char <?php echo $className; ?> :: NULL_STR[2] = { <?php echo $className; ?> ::NULL_CHAR, '\0' }; inline <?php echo $className; ?> :: <?php echo $className; ?> () : length(0), str(""), localStorage(false) { } inline <?php echo $className; ?> :: <?php echo $className; ?> ( <?php echo $className; ?> && o ) : length(o.length), str(o.str), localStorage(o.localStorage) { o.length = 0; o.str = ""; o.localStorage = false; } inline <?php echo $className; ?> :: <?php echo $className; ?> (const GrokitNull & n) : length(1), str(NULL_STR), localStorage(false) { } inline <?php echo $className; ?> :: <?php echo $className; ?> ( const char * _str ) : <?php if ($deepCon) { ?> length(strlen(_str)), str(strdup( _str )), localStorage(true) <?php } else { ?> length(strlen(_str)), str(_str), localStorage(false) <?php } ?> { } inline <?php echo $className; ?> :: <?php echo $className; ?> ( const char *_str, size_t n ) { char * buffer = (char *) malloc( sizeof(char) * (n+1) ); localStorage = true; strncpy(buffer, _str, n); buffer[n] = '\0'; str = buffer; length = strlen(str); } inline <?php echo $className; ?> :: <?php echo $className; ?> ( const std::string & str ) : <?php echo $className; ?> (str.c_str()) { } inline <?php echo $className; ?> :: <?php echo $className; ?> ( const <?php echo $className; ?> & other ) : length(other.length), str(strdup(other.str)), localStorage(true) { } inline <?php echo $className; ?> & <?php echo $className; ?> :: operator = ( const <?php echo $className; ?> & other ) { Clear(); length = other.length; <?php if ($deepAssign) { ?> localStorage = true; str = strdup( other.str ); <?php } else { ?> localStorage = other.localStorage; str = localStorage ? strdup(other.str) : other.str; <?php } ?> return *this; } inline <?php echo $className; ?> :: ~<?php echo $className; ?> () { Clear(); } inline void <?php echo $className; ?> :: Clear() { if( localStorage ) { free((void *) str); str = ""; length = 0; localStorage = false; } } inline char * <?php echo $className; ?> :: Serialize( char * buffer ) const { <?php if ($debug > 0) { ?> std::cout << "Serializing -> " << DebugString() << std::endl; <?php } // if debug > 0 ?> strcpy( buffer, str ); return buffer; } //> inline void * <?php echo $className; ?> :: Serialize( void * buffer ) const { return (void *) Serialize( (char *) buffer ); } inline void <?php echo $className; ?> :: Deserialize( const char * buffer ) { Clear(); str = buffer; length = strlen( str ); <?php if ($debug > 0) { ?> std::cout << "Deserialized -> " << DebugString() << std::endl; <?php } // if debug > 0 ?> } //> // Used for serialization inline int <?php echo $className; ?> :: GetObjLength() const { return length + 1; } // Used for serialization inline <?php echo $className; ?> ::SizeType <?php echo $className; ?> :: GetSize() const { return length + 1; } inline void <?php echo $className; ?> :: Copy( const <?php echo $className; ?> & other ) { Clear(); length = other.length; str = strdup( other.str ); localStorage = true; } inline void <?php echo $className; ?> :: Copy( const char * ostr ) { Clear(); length = strlen(str); str = strdup(ostr); localStorage = true; } inline <?php echo $className; ?> ::SizeType <?php echo $className; ?> :: Length( void ) const { return length; } inline unsigned char <?php echo $className; ?> :: CharAt( int i ) const { return str[i]; } inline bool <?php echo $className; ?> :: IsNull( void ) const { return length == 1 && str[0] == NULL_CHAR; } inline const char * <?php echo $className; ?> :: ToString( void ) const { return str; } inline void <?php echo $className; ?> :: toJson( Json::Value & dest ) const { dest = Json::Value(str); } inline void <?php echo $className; ?> :: fromJson( const Json::Value & src ) { Clear(); str = strdup(src.asCString()); length = strlen(str); localStorage = true; } <?php ob_start(); ?> // Binary serialization template<> inline size_t SizeFromBuffer<@type>(const char * buffer) { return @type::MaxObjectLength; } template<> inline size_t SerializedSize(const @type& from) { return from.GetSize(); } template<> inline size_t Serialize(char * buffer, const @type& from) { from.Serialize(buffer); return SerializedSize(from); } template<> inline size_t Deserialize(const char * buffer, @type& dest) { dest.Deserialize(buffer); return SerializedSize(dest); } // Copy function inline void Copy( @type& to, const @type& from ) { to.Copy( from ); } // ToString for Print inline int ToString( const @type & str, char* text ) { <?php if ($debug > 0) { ?> std::cout << "ToString -> " << str.DebugString() << std::endl; <?php } // if debug > 0 ?> strcpy( text, str.ToString() ); return str.Length() + 1; } // FromString for TextLoader inline void FromString( @type & str, const char * text ) { str = @type(text); <?php if ($debug > 0) { ?> std::cout << "FromString -> " << str.DebugString() << std::endl; <?php } // if debug > 0 ?> } // > inline void ToJson( const @type & src, Json::Value & dest ) { src.toJson(dest); } inline void FromJson( const Json::Value & src, @type & dest ) { dest.fromJson(src); } // ostream operator for easier debugging. template<class CharT, class Traits = std::char_traits<CharT>> std::basic_ostream<CharT, Traits>& operator << ( std::basic_ostream<CharT, Traits> & os, const @type s ) { return os << s.ToString(); //>> } <?php $gContent .= ob_get_clean(); ?> // Operators inline bool operator == (const <?php echo $className; ?> & str1, const <?php echo $className; ?> & str2) { return strcmp( str1.ToString(), str2.ToString() ) == 0; } inline bool operator != (const <?php echo $className; ?> & str1, const <?php echo $className; ?> & str2) { return strcmp( str1.ToString(), str2.ToString() ) != 0; } inline bool operator > (const <?php echo $className; ?> & str1, const <?php echo $className; ?> & str2) { return strcmp( str1.ToString(), str2.ToString() ) > 0; } inline bool operator >= (const <?php echo $className; ?> & str1, const <?php echo $className; ?> & str2) { return strcmp( str1.ToString(), str2.ToString() ) >= 0; } inline bool operator < (const <?php echo $className; ?> & str1, const <?php echo $className; ?> & str2) { return strcmp( str1.ToString(), str2.ToString() ) < 0; } inline bool operator <= (const <?php echo $className; ?> & str1, const <?php echo $className; ?> & str2) { return strcmp( str1.ToString(), str2.ToString() ) <= 0; } inline const char & <?php echo $className; ?> :: operator [] ( SizeType index ) const { return str[index]; } inline const char & <?php echo $className; ?> :: at( SizeType index ) const { FATALIF( index >= length, "Attempting to access character past the end of a STRING."); return str[index]; } <?php ob_start(); ?> // Hash function <?php $functions[] = ['Hash', ['@type'], 'base::BIGINT', true, true]; ?> template<> inline uint64_t Hash( const @type & str ) { return HashString( (void *) str.ToString(), str.Length() ); } // Checking for Nulls <?php $functions[] = ['IsNull', ['@type'], 'BASE::BOOL', true, true]; ?> inline bool IsNull( const @type & str ) { return str.IsNull(); } #ifdef _HAS_STD_HASH #include <functional> // C++11 STL-Compliant hash struct specialization namespace std { template <> class hash<@type> { size_t operator () (const @type & key) const { return Hash( key ); } }; } #endif // _HAS_STD_HASH <?php $gContent .= ob_get_clean(); ?> <?php return array('kind' => 'TYPE', "system_headers" => array("cstring", "cinttypes", 'iostream', 'cstdlib', 'string'), "user_headers" => array("HashFunctions.h", "Constants.h", "Config.h", "Errors.h", "ColumnVarIterator.h"), "complex" => "ColumnVarIterator< @type >", "global_content" => $gContent, 'binary_operators' => ['==', '!=', '>', '<', '>=', '<='], 'constructors' => $constructors, 'methods' => $methods, 'functions' => $functions, 'fixed_size' => false, 'describe_json' => DescribeJson('string'), 'properties' => ['string']); }
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]]; }
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 MACADDR(){ ?> /* This type implements the MAC address Internal representation is an Int (for better efficiency) NOTE: This code has a bug that resuts in mistakes in the mac (loss of the top 2 digits) v<<4 has to come before not after filling in the value with CharToHex */ static char table_map[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; class macAddr { private: static const int HEX_TO_INT[256] __attribute__ ((weak)); //Internal representation of the mac address union mac_rep{ unsigned long long int asInt; struct { unsigned char c1:4; unsigned char c2:4; unsigned char c3:4; unsigned char c4:4; unsigned char c5:4; unsigned char c6:4; unsigned char c7:4; unsigned char c8:4; unsigned char c9:4; unsigned char c10:4; unsigned char c11:4; unsigned char c12:4; }split; }; mac_rep mac; public: //default constructor macAddr() { mac.asInt = 0; } //constructor to convert string into the mac format sepcified format macAddr(const char* addr){ FromString(addr); } //copy constructor macAddr(const macAddr ©Me){ mac.asInt = copyMe.mac.asInt; } //convert from string to the mac format specified above void FromString(const char* addr){ int i = 0; long long int v=0; #define GROUP_OF_MAC \ if (addr[i+1] == ':' || addr[i+1] == 0){ /* short */ \ v <<= 4; \ v |= HexToDecimal (addr[i++]); \ v <<= 4; \ } else /* long */ { \ v |= HexToDecimal (addr[i++]); \ v <<=4; \ v |= HexToDecimal (addr[i++]); \ v <<=4; \ } \ i++ /* skip : */ GROUP_OF_MAC; GROUP_OF_MAC; GROUP_OF_MAC; GROUP_OF_MAC; GROUP_OF_MAC; GROUP_OF_MAC; mac.asInt = v; } //convert the mac address into string int ToString(char *addr) const{ return 1 + std::sprintf(addr, "%c%c:%c%c:%c%c:%c%c:%c%c:%c%c", table_map[mac.split.c1], table_map[mac.split.c12], table_map[mac.split.c11], table_map[mac.split.c10], table_map[mac.split.c9], table_map[mac.split.c8], table_map[mac.split.c7], table_map[mac.split.c6], table_map[mac.split.c5], table_map[mac.split.c4], table_map[mac.split.c3], table_map[mac.split.c2]); } //print the mac address void Print(){ char output[20]; ToString((char*)output); std::cout<<output; } inline int HexToDecimal(char c){ unsigned char index = c; if (HEX_TO_INT[index] >= 0) return HEX_TO_INT[index]; else { FATAL("Error: Invalid MAC Address character: %c", c); } } /* operators */ macAddr& operator=(const macAddr ©Me){ mac.asInt = copyMe.mac.asInt; return *this; } bool operator==(const macAddr &mac2) const { return (mac.asInt == mac2.mac.asInt); } bool operator != (const macAddr &mac2) const { return !(mac.asInt == mac2.mac.asInt); } bool operator < (const macAddr &mac2) const { return (mac.asInt < mac2.mac.asInt); } bool operator <= (const macAddr &mac2) const { return (mac.asInt <= mac2.mac.asInt); } bool operator > (const macAddr &mac2) const { return (mac.asInt > mac2.mac.asInt); } bool operator >= (const macAddr &mac2) const { return (mac.asInt >= mac2.mac.asInt); } uint64_t Hash() const { return mac.asInt; } }; /** * Lookup table for ASCII character to hexidecimal value */ const int macAddr::HEX_TO_INT[256] = { -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 }; <? ob_start(); ?> inline int ToString(const @type& x, char* text){ return x.ToString(text); } inline void FromString(@type& x, const char* text){ x.FromString(text); } inline uint64_t Hash(const @type &mac1){ return mac1.Hash(); } // Deep copy inline void Copy( @type& to, const @type& from ) { to = from; } #ifdef _HAS_STD_HASH #include <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 <? $gContent = ob_get_clean(); ?> typedef macAddr MACADDR; <? return array( 'kind' => 'TYPE', "user_headers" => array ( "Constants.h", "Config.h", "Errors.h" ), "system_headers" => array ( "iostream", "cinttypes" ), "complex" => false, 'binary_operators' => [ '==', '!=', '>', '<', '>=', '<=' ], 'global_content' => $gContent, 'describe_json' => DescribeJson('macaddr'), 'extras' => [ 'size.bytes' => 8 ], ); } // end of function
function FLOAT() { $functions = []; $constructors = []; ?> typedef float FLOAT; // use native int <?php $constructors[] = [['BASE::NULL'], true, 'FLOAT_Null']; ?> inline FLOAT FLOAT_Null( const GrokitNull & n ) { return std::numeric_limits<FLOAT>::quiet_NaN(); } <?php ob_start(); ?> inline void FromString(@type& x, const char* text){ x=atof(text); } inline int ToString(const @type& x, char* text){ // add 1 for the \0 return 1+sprintf(text,"%f", x); } // the hash function // interpret as int (same size) template<> inline uint64_t Hash(const @type& val){ return *( (const unsigned int*)(&val) ); } // Deep copy inline void Copy( @type& to, const @type& from ) { to = from; } <?php $functions[] = ['IsNull', ['@type'], 'BASE::BOOL', true, true]; ?> inline bool IsNull( @type f ) { return isnan(f); } <?php $gContents = ob_get_clean(); ?> ////////////// // Operators // all operators defined by C++ <?php return array('kind' => 'TYPE', "system_headers" => array("cstdlib", "cstdio", "cinttypes", 'cmath', 'limits'), "complex" => false, 'binary_operators' => ['+', '-', '*', '/', '==', '!=', '>', '<', '>=', '<='], 'unary_operators' => ['+', '-'], 'constructors' => $constructors, 'functions' => $functions, 'properties' => ['real', 'numeric', '_primative_'], 'global_content' => $gContents, 'describe_json' => DescribeJson('float'), 'extras' => ['size.bytes' => 4]); }
public static function &GetLibraryManager() { if (self::$instance === null) { self::$instance = new LibraryManager(); // Set up boolean datatype $boolHash = hash('sha256', 'BASE::BOOL'); $extras = ['binary_operators' => ['||', '&&'], 'unary_operators' => ['!'], 'properties' => ['_primative_'], 'describe_json' => DescribeJson('bool')]; $boolDT = new DataType($boolHash, 'BASE::BOOL', 'bool', $extras, [[]]); self::$instance->defineType($boolHash, $boolDT); // Set up null datatype $nullHash = hash('sha256', 'BASE::NULL'); $nullExtras = ['properties' => ['null']]; $nullDT = new DataType($nullHash, 'BASE::NULL', 'GrokitNull', $nullExtras, [[]]); self::$instance->defineType($nullHash, $nullDT); } return self::$instance; }
/** * A fixed-size typed array view on top of memory. The view is read-only * * This is used to prevent copying of data when extracting from a column. */ function FixedArrayView(array $t_args) { $constructors = []; $methods = []; $functions = []; $globalContent = ''; grokit_assert(array_key_exists('type', $t_args), 'FixedArrayView: No type given.'); grokit_assert(array_key_exists('size', $t_args), 'FixedArrayView: No size given'); $type = $t_args['type']; $size = $t_args['size']; if (is_array($type)) { $type = call_user_func_array('lookupType', $type); } else { $type = $type->lookup(); } grokit_assert(is_datatype($type), 'arrayView: [type] argument must be a valid datatype.'); grokit_assert($type->isFixedSize(), 'FixedArray: variable-sized types not supported'); grokit_assert(is_int($size), 'FixedArrayView: [size] argument must be an integer'); grokit_assert($size > 0, 'FixedArrayView: [size] arugment must be a positive number.'); $className = generate_name('FixedArrayView_' . $size . '_'); ?> struct <?php echo $className; ?> { using value_type = <?php echo $type; ?> ; using size_type = std::size_t; using difference_type = std::ptrdiff_t; using reference = value_type &; using const_reference = const value_type &; using pointer = value_type *; using const_pointer = const value_type *; using iterator = value_type *; using const_iterator = const value_type *; using reverse_iterator = std::reverse_iterator<iterator>; using const_reverse_iterator = std::reverse_iterator<const_iterator>; static constexpr const size_type SIZE = <?php echo $size; ?> ; const_pointer __elems_; <?php echo $className; ?> (): __elems_(nullptr) { } // Constructor from externally managed memory <?php echo $className; ?> (const_pointer ptr): __elems_(ptr) { } // Default copy and move constructors/assignment <?php echo $className; ?> (const <?php echo $className; ?> &other) = default; <?php echo $className; ?> & operator=(const <?php echo $className; ?> &other) = default; <?php echo $className; ?> (<?php echo $className; ?> &&other) = default; <?php echo $className; ?> & operator=(<?php echo $className; ?> &&other) = default; /***** Element Access *****/ <?php $methods[] = ['at', ['base::BIGINT'], $type->value(), true]; ?> const_reference at( size_type pos ) const { if( size() <= pos ) { std::ostringstream ss; ss << "Element access out of range:" << " size=" << size() << " index=" << pos; throw std::out_of_range(ss.str()); } return __elems_[pos]; } const_reference operator[]( size_type pos ) const { return __elems_[pos]; } <?php $methods[] = ['front', [], $type->value(), true]; ?> const_reference front() const { return __elems_[0]; } <?php $methods[] = ['back', [], $type->value(), true]; ?> const_reference back() const { return __elems_[SIZE-1]; } const_pointer data() const noexcept { return __elems_; } /***** Iterators *****/ const_iterator cbegin() const noexcept { return __elems_; } const_iterator begin() const noexcept { return cbegin(); } const_iterator cend() const noexcept { return __elems_ + size(); } const_iterator end() const noexcept { return cend(); } const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(cend()); } const_reverse_iterator rbegin() const noexcept { return crbegin(); } const_reverse_iterator crend() const noexcept { return const_reverse_iterator(cbegin()); } const_reverse_iterator rend() const noexcept { return crend(); } /***** Capacity *****/ <?php $methods[] = ['empty', [], 'base::bool', true]; ?> bool empty() const noexcept { return SIZE == 0; } <?php $methods[] = ['size', [], 'base::BIGINT', true]; ?> size_type size() const noexcept { return SIZE; } size_type max_size() const noexcept { return SIZE; } /***** Operations *****/ void swap( <?php echo $className; ?> & other ) noexcept { std::swap( __elems_, other.__elems_ ); } /***** EXTENTIONS *****/ void from_memory( const_pointer mem ) { __elems_ = mem; } }; <?php ob_start(); ?> inline bool operator == ( const @type & lhs, const @type & rhs ) { // Fast-track for views referring to the same memory if (lhs.__elems_ == rhs.__elems_) return true; for( @type::size_type i = 0; i < @type::SIZE; i++ ) { if( lhs[i] != rhs[i] ) return false; } return true; } inline bool operator != ( const @type & lhs, const @type & rhs ) { // Fast-track for views referring to the same memory if (lhs.__elems_ == rhs.__elems_) return false; for( @type::size_type i = 0; i < @type::SIZE; i++ ) { if( lhs[i] != rhs[i] ) return true; } return false; } inline bool operator < ( const @type & lhs, const @type & rhs ) { return std::lexicographical_compare(lhs.cbegin(), lhs.cend(), rhs.cbegin(), rhs.cend()); } inline bool operator > ( const @type & lhs, const @type & rhs ) { return rhs < lhs; } inline bool operator <= ( const @type & lhs, const @type & rhs ) { return !(lhs > rhs); } inline bool operator >=( const @type & lhs, const @type & rhs ) { return !(lhs < rhs); } // ostream operator for easier debugging. template<class CharT, class Traits = std::char_traits<CharT>> std::basic_ostream<CharT, Traits>& operator << ( std::basic_ostream<CharT, Traits> & os, const @type s ) { std::ostringstream ss; bool first = true; ss << "["; for( const auto & elem : s ) { if( first ) { first = false; } else { ss << ", "; } ss << elem; } ss << "]"; os << ss.str(); return os; } template<> inline std::size_t SizeFromBuffer<@type>(const char *buffer) { return @type::SIZE * sizeof(@type::value_type); } template<> inline std::size_t SerializedSize(const @type& from) { return @type::SIZE * sizeof(@type::value_type); } template<> inline std::size_t Serialize(char *buffer, const @type &from) { @type::pointer ptr = reinterpret_cast<@type::pointer>(buffer); std::copy(from.cbegin(), from.cend(), ptr); return SerializedSize(from); } template<> inline std::size_t Deserialize(const char *buffer, @type &dest) { @type::const_pointer ptr = reinterpret_cast<@type::const_pointer>(buffer); dest.from_memory(ptr); return SizeFromBuffer<@type>(buffer); } inline void ToJson( const @type & src, Json::Value & dest ) { dest = Json::Value(Json::arrayValue); for( @type::const_reference elem : src ) { Json::Value tmp; ToJson( elem, tmp ); dest.append(tmp); } } inline int ToString( const @type & x, char * buffer ) { <?php if ($size > 0) { ?> char * start = buffer; char * current = start; for( const auto & val : x ) { current += ToString( val, current ); // Replace null with space *(current-1) = ' '; } // Replace final comma with null *(current-1) = '\0'; return current - start; <?php } else { // if size > 0 ?> buffer[0] = '\0'; return 1; <?php } // if size == 0 ?> } <?php $functions[] = ['Hash', ['@type'], 'BASE::BIGINT', true, true]; ?> template<> inline uint64_t Hash( const @type & val ) { uint64_t hashVal = H_b; for( @type::const_reference elem : val ) { hashVal = CongruentHash(Hash(elem), hashVal); } return hashVal; } namespace std { #ifdef _HAS_STD_HASH // C++11 STL-compliant hash struct specialization template <> class hash<@type> { public: size_t operator () (const @type& key) const { return Hash(key); } }; #endif // _HAS_STD_HASH // std::swap specializations inline void swap( @type& lhs, @type& rhs ) { lhs.swap(rhs); } } <?php $globalContent .= ob_get_clean(); ?> <?php $innerDesc = function ($var, $myType) use($type) { $describer = $type->describer('json'); ?> <?php echo $var; ?> ["size"] = Json::Int64(<?php echo $myType; ?> ::SIZE); <?php $innerVar = "{$var}[\"inner_type\"]"; $describer($innerVar, $type); }; $sys_headers = ['iterator', 'algorithm', 'stdexcept', 'utility', 'cstdint', 'cstddef', 'iostream', 'sstream', 'cstring']; $user_headers = ['Config.h']; $extras = ['size' => $size, 'type' => $type]; $sizeBytes = $size * $type->get('size.bytes'); $extras['size.bytes'] = $sizeBytes; return ['kind' => 'TYPE', 'name' => $className, 'system_headers' => $sys_headers, 'user_headers' => $user_headers, 'constructors' => $constructors, 'methods' => $methods, 'functions' => $functions, 'binary_operators' => ['==', '!=', '<', '>', '<=', '>='], 'global_content' => $globalContent, 'complex' => "ColumnIterator<@type, 0, {$sizeBytes}>", 'properties' => ['container', 'sequence', 'array-view'], 'extras' => $extras, 'describe_json' => DescribeJson('array', $innerDesc)]; }
function BITSET(array $t_args) { grokit_assert(array_key_exists('values', $t_args), 'No values specified for bitset!'); $values = $t_args['values']; $indicies = array_keys($values); $maxIndex = \max($indicies); $minIndex = \min($indicies); grokit_assert($maxIndex < 64, 'Highest index of bitset must be less than 64'); grokit_assert($minIndex >= 0, 'Indicies of bitset must be >= 0'); $mask = 0; foreach ($values as $index => $name) { $firstChar = substr($name, 0, 1); $arr = str_split($name); $valid = array_reduce($arr, function ($res, $item) { $res = $res && (ctype_alnum($item) || $item == '_'); return $res; }, ctype_alpha($firstChar) || $firstChar == '_'); grokit_assert($valid, "Invalid name ({$name}) given for index ({$index}) in bitset."); $mask = $mask | 1 << $index; } $nBits = floor(pow(2, ceil(log($maxIndex + 1, 2)))); $nBits = \max(8, $nBits); $nHex = $nBits / 4; $storageType = "uint{$nBits}_t"; switch ($nBits) { case 8: $methodIntType = 'base::BYTE'; break; case 16: $methodIntType = 'base::SMALLINT'; break; case 32: $methodIntType = 'base::INT'; break; case 64: $methodIntType = 'base::BIGINT'; break; default: grokit_error('BITSET requires invalid number of bits (' . $nBits . ')'); } $className = generate_name('BITSET'); $methods = []; $constructors = []; $functions = []; $globalContents = ""; ?> class <?php echo $className; ?> { public: typedef <?php echo $storageType; ?> StorageType; private: StorageType bits; static constexpr StorageType _MASK_ = 0x<?php echo sprintf("%0{$nHex}X", $mask); ?> ; public: <?php echo $className; ?> (void); <?php $constructors[] = [[$methodIntType], true]; ?> <?php echo $className; ?> (const StorageType _bits); <?php echo $className; ?> & operator =( const StorageType _bits ); /***** Comparison Opeators *****/ bool operator ==( const <?php echo $className; ?> & o ) const; bool operator !=( const <?php echo $className; ?> & o ) const; bool operator <( const <?php echo $className; ?> & o ) const; bool operator >( const <?php echo $className; ?> & o ) const; bool operator <=( const <?php echo $className; ?> & o ) const; bool operator >=( const <?php echo $className; ?> & o ) const; /***** Conversion *****/ void ToJson( Json::Value & dest ) const; void FromJson( const Json::Value & src ); /***** Accessors *****/ <?php $methods[] = ['Bits', [], $methodIntType, true]; ?> StorageType Bits(void) const; <?php $methods[] = ['IsSet', ['base::BYTE'], 'base::bool', true]; ?> // Whether or not a bit is set by index bool IsSet(unsigned char index) const; // Accessors for each value <?php foreach ($values as $index => $name) { $methods[] = [$name, [], 'base::bool', true]; ?> bool <?php echo $name; ?> (void) const; <?php } // for each value ?> }; inline <?php echo $className; ?> :: <?php echo $className; ?> ( void ) : bits(0) { } inline <?php echo $className; ?> :: <?php echo $className; ?> ( const StorageType _bits ) : bits(_bits) { } inline <?php echo $className; ?> & <?php echo $className; ?> :: operator = (const StorageType _bits) { bits = _bits; return *this; } inline bool <?php echo $className; ?> :: operator == (const <?php echo $className; ?> & o ) const { return bits == o.bits; } inline bool <?php echo $className; ?> :: operator != (const <?php echo $className; ?> & o ) const { return bits != o.bits; } inline bool <?php echo $className; ?> :: operator < (const <?php echo $className; ?> & o ) const { return (bits == (bits & o.bits)) && (bits != o.bits); } inline bool <?php echo $className; ?> :: operator > (const <?php echo $className; ?> & o ) const { return (bits == (bits | o.bits)) && (bits != o.bits); } inline bool <?php echo $className; ?> :: operator <= (const <?php echo $className; ?> & o ) const { return bits == (bits & o.bits); } inline bool <?php echo $className; ?> :: operator >= (const <?php echo $className; ?> & o ) const { return bits == (bits | o.bits); } inline auto <?php echo $className; ?> :: Bits( void ) const -> StorageType { return bits; } inline bool <?php echo $className; ?> ::IsSet(unsigned char index) const { StorageType mask = ((StorageType) 1) << index; //> return bits & mask; } inline void <?php echo $className; ?> :: ToJson( Json::Value & dest ) const { dest = (Json::Int64) bits; } inline void <?php echo $className; ?> :: FromJson( const Json::Value & src ) { bits = (StorageType) src.asInt64(); } <?php foreach ($values as $index => $name) { ?> bool <?php echo $className; ?> ::<?php echo $name; ?> (void) const { return bits & 0x<?php echo sprintf("%X", 1 << $index); ?> ; } <?php } // for each value ?> <?php ob_start(); ?> <?php $functions[] = ['Hash', ['@type'], 'base::BIGINT', true, true]; ?> template<> inline uint64_t Hash(const @type & thing) { return thing.Bits(); } inline void FromString( @type & c, const char * str ) { c = atol(str); } inline int ToString( const @type & c, char * buffer ) { <?php $format = $nBits < 16 ? 'hh' : ($nBits < 32 ? 'h' : ($nBits < 64 ? '' : 'l')); ?> sprintf(buffer, "%<?php echo $format; ?> d", c.Bits()); return strlen(buffer) + 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 $globalContents .= ob_get_clean(); ?> <?php return ['kind' => 'TYPE', 'name' => $className, 'binary_operators' => ['==', '!=', '>', '<', '>=', '<='], 'system_headers' => ['cinttypes'], 'global_content' => $globalContents, 'complex' => false, 'methods' => $methods, 'constructors' => $constructors, 'functions' => $functions, 'describe_json' => DescribeJson('integer'), 'extras' => ['size.bytes' => $nBits / 8]]; }
function SMALLINT() { // global content $gContent = ""; $functions = []; $constructors = []; $nullVal = "-1"; ?> typedef short SMALLINT; <?php $constructors[] = [['BASE::NULL'], true, 'SMALLINT_Null']; ?> inline SMALLINT SMALLINT_Null( const GrokitNull & n ) { return <?php echo $nullVal; ?> ; } <?php ob_start(); ?> inline void FromString(@type & x, const char* text){ x = (short) atoi(text); } inline int ToString(const @type & x, char* text){ // add 1 for the \0 return 1+sprintf(text,"%hd", x); } // The hash function // we just use conversion to unsigned int template<> inline uint64_t Hash(const @type& x){ return x;} // Deep copy inline void Copy( @type & to, const @type & from ) { to = from; } <?php $functions[] = ['IsNull', ['@type'], 'BASE::BOOL', true, true]; ?> inline bool IsNull( const @type t ) { return t == <?php echo $nullVal; ?> ; } <?php $gContent .= ob_get_clean(); ?> ////////////// // Operators // all operators defined by C++ <?php return array('kind' => 'TYPE', "system_headers" => array("cstdlib", "cstdio", "cinttypes", 'limits'), "complex" => false, "global_content" => $gContent, 'binary_operators' => ['+', '-', '*', '/', '%', '==', '!=', '>', '<', '>=', '<='], 'unary_operators' => ['+', '-'], 'constructors' => $constructors, 'functions' => $functions, 'properties' => ['integral', 'numeric', '_primative_'], 'describe_json' => DescribeJson('integer'), 'extras' => ['size.bytes' => 2]); }
function LOCATION() { $constructors = []; $methods = []; $functions = []; $systemHeaders = ['math.h', 'cstdio']; $libHeaders = []; $libraries = []; $globalContent = ""; ?> class LOCATION { private: // The radius of the Earth at the equator, measured in km. static constexpr const double kRadius = 6378.137; // The ratio between a degree and a radian. static constexpr const double kRatio = 0.01745329251994329576923; // The latitudinal angle measured in radians. Positive values correspond to // northerly locations. double latitude; // The longitudinal angle measured in radians. Positive values correspond to // easterly locations. double longitude; // The elevation measured in meters relative to the sea level. double elevation; public: <?php $constructors[] = [[], true]; ?> constexpr LOCATION() : latitude(0), longitude(0), elevation(0) { } <?php //$constructors[] = [['base::double', 'base::double'], true]; //$constructors[] = [['base::double', 'base::double', 'base::bool'], true]; ?> constexpr LOCATION(double latitude, double longitude, bool radians = false) : latitude(latitude * (radians ? kRatio : 1)), longitude(longitude * (radians ? kRatio : 1)), elevation(0) { } <?php $constructors[] = [['base::double', 'base::double', 'base::double'], true]; $constructors[] = [['base::double', 'base::double', 'base::double', 'base::bool'], true]; ?> constexpr LOCATION(double latitude, double longitude, double elevation, bool radians = false) : latitude(latitude * (radians ? kRatio : 1)), longitude(longitude * (radians ? kRatio : 1)), elevation(elevation) { } <?php $constructors[] = [['base::double', 'base::double', 'base::double', 'base::double', 'base::double', 'base::double', 'base::double'], true]; $constructors[] = [['base::double', 'base::double', 'base::double', 'base::double', 'base::double', 'base::double'], true]; ?> constexpr LOCATION(double lat_degree, double lat_minute, double lat_second, double lng_degree, double lng_minute, double lng_second, double elevation = 0) : latitude((lat_degree + lat_minute / 60 + lat_second / 3600) * kRatio), longitude((lng_degree + lng_minute / 60 + lng_second / 3600) * kRatio), elevation(elevation) { } <?php $methods[] = ['Haversine', ['@type'], 'base::double', true]; ?> double Haversine(const LOCATION other) const { const double chord = pow(sin((latitude - other.latitude) / 2), 2) + pow(sin((longitude - other.longitude) / 2), 2) * cos(latitude) * cos(other.latitude); return 2 * kradius * asin(sqrt(chord)); } void FromString(const char* buffer) { sscanf(buffer, "%f %f %f", &latitude, &longitude, &elevation); latitude *= kRatio; longitude *= kRatio; } int ToString(char* buffer) const { return 1 + sprintf(buffer, "%f %f %f", latitude / kRatio, longitude / kRatio, elevation); } void FromJson(const Json::Value& src) { latitude = src["lat"].asDouble() * kRatio; longitude = src["lng"].asDouble() * kRatio; elevation = src["elv"].asDouble(); } void ToJson(Json::Value& dest) const { dest["lat"] = latitude / kRatio; dest["lng"] = longitude / kRatio; dest["elv"] = elevation; } }; <?php $functions[] = ['Haversine', ['@type', '@type'], 'BASE::DOUBLE', true, false]; ?> inline double Haversine(const LOCATION loc_1, const LOCATION loc_2) { return loc_1.Haversine(loc_2); } <?php ob_start(); ?> inline void FromString(@type& location, const char* buffer) { location.FromString(buffer); } inline int ToString(const @type& location, char* buffer) { return location.ToString(bufffer); } inline void FromJson(const Json::Value& src, @type& dest) { dest.FromJson(src); } inline void ToJson(@type& src, Json::Value& dest) { src.ToJson(dest); } <?php $globalContent .= ob_get_clean(); ?> <?php return ['kind' => 'TYPE', 'complex' => false, 'system_headers' => $systemHeaders, 'global_content' => $globalContent, 'constructors' => $constructors, 'methods' => $methods, 'functions' => $functions, 'libraries' => $libraries, 'properties' => [], 'describe_json' => DescribeJson('location'), 'extras' => ['size.bytes' => 24]]; }