Library to allo USB PTP device to be hosted by the mbed platform

Dependents:   class_project_main

Revision:
10:fc1cb68fc91e
diff -r 961c3357504d -r fc1cb68fc91e PIMA15740/uint128_t..h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/PIMA15740/uint128_t..h	Wed Sep 18 01:48:07 2013 +0000
@@ -0,0 +1,600 @@
+/*
+uint128_t.h
+An unsigned 128 bit integer library for C++
+By Jason Lee @ calccrypto@yahoo.com
+with much help from Auston Sterling
+ 
+And thanks to Stefan Deigmüller for finding
+a bug in operator*.
+*/
+ 
+#ifndef UINT128_T_H
+#define UINT128_T_H
+ 
+#include <cstdlib>
+#include <iostream>
+#include <stdint.h>
+ 
+class uint128_t{
+    private:
+        uint64_t UPPER, LOWER;
+ 
+    public:
+        // Constructors
+        uint128_t(){
+            UPPER = 0;
+            LOWER = 0;
+        }
+ 
+        template <typename T>
+        uint128_t(T rhs){
+            UPPER = 0;
+            LOWER = (uint64_t) rhs;
+        }
+ 
+        template <typename S, typename T>
+        uint128_t(const S upper_rhs, const T lower_rhs){
+            UPPER = (uint64_t) upper_rhs;
+            LOWER = (uint64_t) lower_rhs;
+        }
+ 
+        uint128_t(const uint128_t & rhs){
+            UPPER = rhs.UPPER;
+            LOWER = rhs.LOWER;
+        }
+ 
+        //  RHS input args only
+ 
+        // Assignment Operator
+        template <typename T> uint128_t operator=(T rhs){
+            UPPER = 0;
+            LOWER = (uint64_t) rhs;
+            return *this;
+        }
+ 
+        uint128_t operator=(uint128_t rhs){
+            UPPER = rhs.UPPER;
+            LOWER = rhs.LOWER;
+            return *this;
+        }
+ 
+        // Typecast Operators
+        operator bool(){
+            return (bool) (UPPER | LOWER);
+        }
+ 
+        operator char(){
+            return (char) LOWER;
+        }
+ 
+        operator int(){
+            return (int) LOWER;
+        }
+ 
+        operator uint8_t(){
+            return (uint8_t) LOWER;
+        }
+ 
+        operator uint16_t(){
+            return (uint16_t) LOWER;
+        }
+ 
+        operator uint32_t(){
+            return (uint32_t) LOWER;
+        }
+ 
+        operator uint64_t(){
+            return LOWER;
+        }
+ 
+        // Bitwise Operators
+        template <typename T> uint128_t operator&(T rhs){
+            return uint128_t(0, LOWER & (uint64_t) rhs);
+        }
+ 
+        uint128_t operator&(uint128_t rhs){
+            return uint128_t(UPPER & rhs.UPPER, LOWER & rhs.LOWER);
+        }
+ 
+        template <typename T> uint128_t operator|(T rhs){
+            return uint128_t(UPPER, LOWER | (uint64_t) rhs);
+        }
+ 
+        uint128_t operator|(uint128_t rhs){
+            return uint128_t(UPPER | rhs.UPPER, LOWER | rhs.LOWER);
+        }
+ 
+        template <typename T> uint128_t operator^(T rhs){
+            return uint128_t(UPPER, LOWER ^ (uint64_t) rhs);
+        }
+ 
+        uint128_t operator^(uint128_t rhs){
+            return uint128_t(UPPER ^ rhs.UPPER, LOWER ^ rhs.LOWER);
+        }
+ 
+        template <typename T> uint128_t operator&=(T rhs){
+            UPPER = 0;
+            LOWER &= rhs;
+            return *this;
+        }
+ 
+        uint128_t operator&=(uint128_t rhs){
+            UPPER &= rhs.UPPER;
+            LOWER &= rhs.LOWER;
+            return *this;
+        }
+ 
+        template <typename T> uint128_t operator|=(T rhs){
+            LOWER |= (uint64_t) rhs;
+            return *this;
+        }
+ 
+        uint128_t operator|=(uint128_t rhs){
+            UPPER |= rhs.UPPER;
+            LOWER |= rhs.LOWER;
+            return *this;
+        }
+ 
+        template <typename T> uint128_t operator^=(T rhs){
+            LOWER ^= (uint64_t) rhs;
+            return *this;
+        }
+ 
+        uint128_t operator^=(const uint128_t rhs){
+            UPPER ^= rhs.UPPER;
+            LOWER ^= rhs.LOWER;
+            return *this;
+        }
+ 
+        uint128_t operator~(){
+            return uint128_t(~UPPER, ~LOWER);
+        }
+ 
+        // Bit Shift Operators
+        template <typename T>
+        uint128_t operator<<(const T shift){
+            if (shift >= 128)
+                return uint128_t(0, 0);
+            else if (shift == 64)
+                return uint128_t(LOWER, 0);
+            else if (shift == 0)
+                return *this;
+            else if (shift < 64)
+                return uint128_t((UPPER << shift) + (LOWER >> (64 - shift)), LOWER << shift);
+            else if ((128 > shift) && (shift > 64))
+                return uint128_t(LOWER << (shift - 64), 0);
+            else
+                return uint128_t(0);
+        }
+ 
+        template <typename T>
+        uint128_t operator>>(const T shift){
+            if (shift >= 128)
+                return uint128_t(0, 0);
+            else if (shift == 64)
+                return uint128_t(0, UPPER);
+            else if (shift == 0)
+                return *this;
+            else if (shift < 64)
+                return uint128_t(UPPER >> shift, (UPPER << (64 - shift)) + (LOWER >> shift));
+            else if ((128 > shift) && (shift > 64))
+                return uint128_t(0, (UPPER >> (shift - 64)));
+            else
+                return uint128_t(0);
+        }
+ 
+        uint128_t operator<<=(int shift){
+            *this = *this << shift;
+            return *this;
+        }
+ 
+        uint128_t operator>>=(int shift){
+            *this = *this >> shift;
+            return *this;
+        }
+ 
+        // Logical Operators
+        bool operator!(){
+            return !(bool) (UPPER | LOWER);
+        }
+ 
+        template <typename T> bool operator&&(T rhs){
+            return (bool) *this && rhs;
+        }
+ 
+        template <typename T> bool operator&&(uint128_t rhs){
+            return (bool) *this && (bool) rhs;
+        }
+ 
+        template <typename T> bool operator||(T rhs){
+            return ((bool) *this) || rhs;
+ 
+        }
+ 
+        template <typename T> bool operator||(uint128_t rhs){
+            return ((bool) *this) || (bool) rhs;
+        }
+ 
+        // Comparison Operators
+        template <typename T> bool operator==(T rhs){
+            return (!UPPER && (LOWER == (uint64_t) rhs));
+        }
+ 
+        bool operator==(uint128_t rhs){
+            return ((UPPER == rhs.UPPER) && (LOWER == rhs.LOWER));
+        }
+ 
+        template <typename T> bool operator!=(T rhs){
+            return (UPPER | (LOWER != (uint64_t) rhs));
+        }
+ 
+        bool operator!=(uint128_t rhs){
+            return ((UPPER != rhs.UPPER) | (LOWER != rhs.LOWER));
+        }
+ 
+        template <typename T> bool operator>(T rhs){
+            if (UPPER)
+                return true;
+            return (LOWER > (uint64_t) rhs);
+        }
+ 
+        bool operator>(uint128_t rhs){
+            if (UPPER == rhs.UPPER)
+                return (LOWER > rhs.LOWER);
+            if (UPPER > rhs.UPPER)
+                return true;
+            return false;
+        }
+ 
+        template <typename T> bool operator<(T rhs){
+            if  (!UPPER)
+                return (LOWER < (uint64_t) rhs);
+            return false;
+        }
+ 
+        bool operator<(uint128_t rhs){
+            if (UPPER == rhs.UPPER)
+                return (LOWER < rhs.LOWER);
+            if (UPPER < rhs.UPPER)
+                return true;
+            return false;
+        }
+ 
+        template <typename T> bool operator>=(T rhs){
+            return ((*this > rhs) | (*this == rhs));
+        }
+ 
+        bool operator>=(uint128_t rhs){
+            return ((*this > rhs) | (*this == rhs));
+        }
+ 
+        template <typename T> bool operator<=(T rhs){
+            return ((*this < rhs) | (*this == rhs));
+        }
+ 
+        bool operator<=(uint128_t rhs){
+            return ((*this < rhs) | (*this == rhs));
+        }
+ 
+        // Arithmetic Operators
+        template <typename T> uint128_t operator+(T rhs){
+            return uint128_t(UPPER + ((LOWER + (uint64_t) rhs) < LOWER), LOWER + (uint64_t) rhs);
+        }
+ 
+        uint128_t operator+(uint128_t rhs){
+            return uint128_t(rhs.UPPER + UPPER + ((LOWER + rhs.LOWER) < LOWER), LOWER + rhs.LOWER);
+        }
+ 
+        template <typename T> uint128_t operator+=(T rhs){
+            UPPER = UPPER + ((LOWER + rhs) < LOWER);
+            LOWER = LOWER + rhs;
+            return *this;
+        }
+ 
+        uint128_t operator+=(uint128_t rhs){
+            UPPER = rhs.UPPER + UPPER + ((LOWER + rhs.LOWER) < LOWER);
+            LOWER = LOWER + rhs.LOWER;
+            return *this;
+        }
+ 
+        template <typename T> uint128_t  operator-(T rhs){
+            return uint128_t((uint64_t) (UPPER - ((LOWER - rhs) > LOWER)), (uint64_t) (LOWER - rhs));
+        }
+ 
+        uint128_t  operator-(uint128_t rhs){
+            return uint128_t(UPPER - rhs.UPPER - ((LOWER - rhs.LOWER) > LOWER), LOWER - rhs.LOWER);
+        }
+ 
+        template <typename T> uint128_t operator-=(T rhs){
+            *this = *this - rhs;
+            return *this;
+        }
+ 
+        uint128_t operator-=(uint128_t rhs){
+            *this = *this - rhs;
+            return *this;
+        }
+ 
+        template <typename T> uint128_t operator*(T rhs){
+            return *this * uint128_t(rhs);
+        }
+ 
+        uint128_t operator*(uint128_t rhs){
+            // split values into 4 32-bit parts
+            uint64_t top[4] = {UPPER >> 32, UPPER % 0x100000000ULL, LOWER >> 32, LOWER % 0x100000000ULL};
+            uint64_t bottom[4] = {rhs.upper() >> 32, rhs.upper() % 0x100000000ULL, rhs.lower() >> 32, rhs.lower() % 0x100000000ULL};
+            uint64_t products[4][4];
+ 
+            for(int y = 3; y > -1; y--)
+                for(int x = 3; x > -1; x--){
+                    products[3 - x][y] = top[x] * bottom[y];
+            }
+ 
+            // initial row
+            uint64_t fourth32 = products[0][3] % 0x100000000ULL;
+            uint64_t third32 = products[0][2] % 0x100000000ULL + (products[0][3] >> 32);
+            uint64_t second32 = products[0][1] % 0x100000000ULL + (products[0][2] >> 32);
+            uint64_t first32 = products[0][0] % 0x100000000ULL + (products[0][1] >> 32);
+ 
+            // second row
+            third32 += products[1][3] % 0x100000000ULL;
+            second32 += (products[1][2] % 0x100000000ULL) + (products[1][3] >> 32);
+            first32 += (products[1][1] % 0x100000000ULL) + (products[1][2] >> 32);
+ 
+            // third row
+            second32 += products[2][3] % 0x100000000ULL;
+            first32 += (products[2][2] % 0x100000000ULL) + (products[2][3] >> 32);
+ 
+            // fourth row
+            first32 += products[3][3] % 0x100000000ULL;
+ 
+            // combines the values, taking care of carry over
+            return uint128_t(first32 << 32, 0) + uint128_t(third32 >> 32, third32 << 32) + uint128_t(second32, 0) + uint128_t(fourth32);
+        }
+ 
+        template <typename T> uint128_t operator*=(T rhs){
+            *this = *this * uint128_t(rhs);
+            return *this;
+        }
+ 
+        uint128_t operator*=(uint128_t rhs){
+            *this = *this * rhs;
+            return *this;
+        }
+ 
+        template <typename T> uint128_t operator/(T rhs){
+            return *this / uint128_t(rhs);
+        }
+ 
+        uint128_t operator/(uint128_t rhs){
+            // Save some calculations /////////////////////
+            if (rhs == 0){
+                std::cout << "Error: division or modulus by zero" << std::endl;
+                exit(1);
+            }
+            if (rhs == 1)
+                return *this;
+            if (*this == rhs)
+                return uint128_t(1);
+            if ((*this == 0) | (*this < rhs))
+                return uint128_t(0);
+            // Checks for divisors that are powers of two
+            uint16_t s = 0;
+            uint128_t copyd(rhs);
+            while ((copyd.LOWER & 1) == 0){
+                copyd >>= 1;
+                s++;
+            }
+            if (copyd == 1)
+                return *this >> s;
+            ////////////////////////////////////////////////
+            uint128_t copyn(*this), quotient = 0;
+            while (copyn >= rhs){
+                uint128_t copyd(rhs), temp(1);
+                // shift the divsor to match the highest bit
+                while ((copyn >> 1) > copyd){
+                    copyd <<= 1;
+                    temp <<= 1;
+                }
+                copyn -= copyd;
+                quotient += temp;
+            }
+            return quotient;
+        }
+ 
+        template <typename T> uint128_t operator/=(T rhs){
+            *this = *this / uint128_t(rhs);
+            return *this;
+        }
+ 
+        uint128_t operator/=(uint128_t rhs){
+            *this = *this / rhs;
+            return *this;
+        }
+ 
+        template <typename T> uint128_t operator%(T rhs){
+            return *this - (rhs * (*this / rhs));
+        }
+ 
+        uint128_t operator%(uint128_t rhs){
+            return *this - (rhs * (*this / rhs));
+        }
+ 
+        template <typename T> uint128_t operator%=(T rhs){
+            *this = *this % uint128_t(rhs);
+            return *this;
+        }
+ 
+        uint128_t operator%=(uint128_t rhs){
+            *this = *this % rhs;
+            return *this;
+        }
+ 
+        // Increment Operator
+        uint128_t operator++(){
+            *this += 1;
+            return *this;
+        }
+ 
+        uint128_t operator++(int){
+            uint128_t temp(*this);
+            ++*this;
+            return temp;
+        }
+ 
+        // Decrement Operator
+        uint128_t operator--(){
+            *this -= 1;
+            return *this;
+        }
+ 
+        uint128_t operator--(int){
+            uint128_t temp(*this);
+            --*this;
+            return temp;
+        }
+ 
+        // get private values
+        uint64_t upper(){
+            return UPPER;
+        }
+ 
+        uint64_t lower(){
+            return LOWER;
+        }
+};
+// lhs type T as first arguemnt
+ 
+// Bitwise Operators
+template <typename T> T operator&(T lhs, uint128_t rhs){
+    T out = lhs & (T) rhs.lower();
+    return out;
+}
+ 
+template <typename T> T operator|(T lhs, uint128_t rhs){
+    T out = lhs | (T) rhs.lower();
+    return out;
+}
+ 
+template <typename T> T operator^(T lhs, uint128_t rhs){
+    T out = lhs ^ (T) rhs.lower();
+    return out;
+}
+ 
+template <typename T> T operator&=(T & lhs, uint128_t rhs){
+    lhs &= (T) rhs.lower();
+    return lhs;
+}
+ 
+template <typename T> T operator|=(T & lhs, uint128_t rhs){
+    lhs |= (T) rhs.lower();
+    return lhs;
+}
+ 
+template <typename T> T operator^=(T & lhs, uint128_t rhs){
+    lhs ^= (T) rhs.lower();
+    return lhs;
+}
+ 
+// Comparison Operators
+template <typename T> bool operator==(T lhs, uint128_t rhs){
+    return (!rhs.upper() && ((uint64_t) lhs == rhs.lower()));
+}
+ 
+template <typename T> bool operator!=(T lhs, uint128_t rhs){
+    return (rhs.upper() | ((uint64_t) lhs != rhs.lower()));
+}
+ 
+template <typename T> bool operator>(T lhs, uint128_t rhs){
+    if (rhs.upper())
+        return false;
+    return ((uint64_t) lhs > rhs.lower());
+}
+ 
+template <typename T> bool operator<(T lhs, uint128_t rhs){
+    if (rhs.upper())
+        return true;
+    return ((uint64_t) lhs < rhs.lower());
+}
+ 
+template <typename T> bool operator>=(T lhs, uint128_t rhs){
+    if (rhs.upper())
+        return false;
+    return ((uint64_t) lhs >= rhs.lower());
+}
+ 
+template <typename T> bool operator<=(T lhs, uint128_t rhs){
+    if (rhs.upper())
+        return true;
+    return ((uint64_t) lhs <= rhs.lower());
+}
+ 
+// Arithmetic Operators
+template <typename T> T operator+(T lhs, uint128_t rhs){
+    return (T) (rhs + lhs);
+}
+ 
+template <typename T> T & operator+=(T & lhs, uint128_t rhs){
+    lhs = (T) (rhs + lhs);
+    return lhs;
+}
+ 
+template <typename T> T operator-(T lhs, uint128_t rhs){
+    return (T) (rhs - lhs);
+}
+ 
+template <typename T> T & operator-=(T & lhs, uint128_t rhs){
+    lhs = (T) (rhs - lhs);
+    return lhs;
+}
+ 
+template <typename T> T operator*(T lhs, uint128_t rhs){
+    return lhs * rhs.lower();
+}
+ 
+template <typename T> T & operator*=(T & lhs, uint128_t rhs){
+    lhs = (T) (rhs.lower() * lhs);
+    return lhs;
+}
+ 
+template <typename T> T operator/(T lhs, uint128_t rhs){
+    return (T) (uint128_t(lhs) / rhs);
+}
+ 
+template <typename T> T & operator/=(T & lhs, uint128_t rhs){
+    lhs = (T) (uint128_t(lhs) / rhs);
+    return lhs;
+}
+ 
+template <typename T> T operator%(T lhs, uint128_t rhs){
+    return (T) (uint128_t(lhs) % rhs);
+}
+ 
+template <typename T> T & operator%=(T & lhs, uint128_t rhs){
+    lhs = (T) (uint128_t(lhs) % rhs);
+    return lhs;
+}
+ 
+// IO Operator
+std::ostream & operator<<(std::ostream & stream, uint128_t rhs){
+    std::string out = "";
+    if (rhs == 0)
+        out = "0";
+    else {
+        int div = 10;
+        if (stream.flags() & stream.oct)
+            div = 8;
+        if (stream.flags() & stream.dec)
+            div = 10;
+        if (stream.flags() & stream.hex)
+            div = 16;
+        while (rhs > 0){
+            out = "0123456789abcdef"[size_t(rhs % div)] + out;
+            rhs /= div;
+        }
+    }
+    stream << out;
+    return stream;
+}
+ 
+#endif // UINT128_T_H