Ejemplo n.º 1
0
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]))];
}
Ejemplo n.º 2
0
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]];
}
Ejemplo n.º 3
0
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];
}
Ejemplo n.º 4
0
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];
}
Ejemplo n.º 5
0
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]);
}
Ejemplo n.º 6
0
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];
}
Ejemplo n.º 7
0
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]];
}