Squashed 'third_party/boostorg/serialization/' content from commit 738695b

Change-Id: I48528198ad1f62b90288d249eb2243d4db02fd5d
git-subtree-dir: third_party/boostorg/serialization
git-subtree-split: 738695b70733f9d592a570fb17a505d6a029b48a
diff --git a/performance/xml/high_resolution_timer.hpp b/performance/xml/high_resolution_timer.hpp
new file mode 100644
index 0000000..afa5495
--- /dev/null
+++ b/performance/xml/high_resolution_timer.hpp
@@ -0,0 +1,489 @@
+//  Copyright (c) 2005-2010 Hartmut Kaiser
+//  Copyright (c) 2009      Edward Grace
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(HIGH_RESOLUTION_TIMER_MAR_24_2008_1222PM)
+#define HIGH_RESOLUTION_TIMER_MAR_24_2008_1222PM
+
+#include <boost/config.hpp>
+#include <boost/throw_exception.hpp>
+
+#if defined(BOOST_HAS_UNISTD_H)
+#include <unistd.h>
+#endif
+#include <time.h>
+#include <stdexcept>
+#include <limits>
+
+#if defined(BOOST_WINDOWS)
+
+#include <windows.h>
+
+namespace boost {
+namespace archive {
+namespace xml {
+    ///////////////////////////////////////////////////////////////////////////////
+    //
+    //  high_resolution_timer 
+    //      A timer object measures elapsed time.
+    //      CAUTION: Windows only!
+    //
+    ///////////////////////////////////////////////////////////////////////////////
+    class high_resolution_timer
+    {
+    public:
+        high_resolution_timer() 
+        {
+            restart(); 
+        } 
+
+        high_resolution_timer(double t) 
+        {
+            LARGE_INTEGER frequency;
+            if (!QueryPerformanceFrequency(&frequency))
+                boost::throw_exception(std::runtime_error("Couldn't acquire frequency"));
+
+            start_time.QuadPart = (LONGLONG)(t * frequency.QuadPart); 
+        } 
+
+        high_resolution_timer(high_resolution_timer const& rhs) 
+          : start_time(rhs.start_time)
+        {
+        } 
+
+        static double now()
+        {
+            SYSTEMTIME st;
+            GetSystemTime(&st);
+
+            FILETIME ft;
+            SystemTimeToFileTime(&st, &ft);
+
+            LARGE_INTEGER now;
+            now.LowPart = ft.dwLowDateTime;
+            now.HighPart = ft.dwHighDateTime;
+
+            // FileTime is in 100ns increments, result needs to be in [s]
+            return now.QuadPart * 1e-7;
+        }
+
+        void restart() 
+        { 
+            if (!QueryPerformanceCounter(&start_time))
+                boost::throw_exception(std::runtime_error("Couldn't initialize start_time"));
+        } 
+        double elapsed() const                  // return elapsed time in seconds
+        { 
+            LARGE_INTEGER now;
+            if (!QueryPerformanceCounter(&now))
+                boost::throw_exception(std::runtime_error("Couldn't get current time"));
+
+            LARGE_INTEGER frequency;
+            if (!QueryPerformanceFrequency(&frequency))
+                boost::throw_exception(std::runtime_error("Couldn't acquire frequency"));
+
+            return double(now.QuadPart - start_time.QuadPart) / frequency.QuadPart;
+        }
+
+        double elapsed_max() const   // return estimated maximum value for elapsed()
+        {
+            LARGE_INTEGER frequency;
+            if (!QueryPerformanceFrequency(&frequency))
+                boost::throw_exception(std::runtime_error("Couldn't acquire frequency"));
+
+            return double((std::numeric_limits<LONGLONG>::max)() - start_time.QuadPart) / 
+                double(frequency.QuadPart); 
+        }
+
+        double elapsed_min() const            // return minimum value for elapsed()
+        { 
+            LARGE_INTEGER frequency;
+            if (!QueryPerformanceFrequency(&frequency))
+                boost::throw_exception(std::runtime_error("Couldn't acquire frequency"));
+
+            return 1.0 / frequency.QuadPart; 
+        }
+
+    private:
+        LARGE_INTEGER start_time;
+    }; 
+
+} // xml
+} // archive
+} // boost
+
+#elif defined(_POSIX_TIMERS) && _POSIX_TIMERS > 0 && defined(_POSIX_THREAD_CPUTIME)
+
+#if _POSIX_THREAD_CPUTIME > 0   // timer always supported
+
+namespace boost {
+namespace archive {
+namespace xml {
+
+    ///////////////////////////////////////////////////////////////////////////////
+    //
+    //  high_resolution_timer 
+    //      A timer object measures elapsed time.
+    //
+    ///////////////////////////////////////////////////////////////////////////////
+    class high_resolution_timer
+    {
+    public:
+        high_resolution_timer() 
+        {
+            start_time.tv_sec = 0;
+            start_time.tv_nsec = 0;
+
+            restart(); 
+        } 
+
+        high_resolution_timer(double t) 
+        {
+            start_time.tv_sec = time_t(t);
+            start_time.tv_nsec = (t - start_time.tv_sec) * 1e9;
+        }
+
+        high_resolution_timer(high_resolution_timer const& rhs) 
+          : start_time(rhs.start_time)
+        {
+        } 
+
+        static double now()
+        {
+            timespec now;
+            if (-1 == clock_gettime(CLOCK_REALTIME, &now))
+                boost::throw_exception(std::runtime_error("Couldn't get current time"));
+            return double(now.tv_sec) + double(now.tv_nsec) * 1e-9;
+        }
+
+        void restart() 
+        { 
+            if (-1 == clock_gettime(CLOCK_REALTIME, &start_time))
+                boost::throw_exception(std::runtime_error("Couldn't initialize start_time"));
+        } 
+        double elapsed() const                  // return elapsed time in seconds
+        { 
+            timespec now;
+            if (-1 == clock_gettime(CLOCK_REALTIME, &now))
+                boost::throw_exception(std::runtime_error("Couldn't get current time"));
+
+            if (now.tv_sec == start_time.tv_sec)
+                return double(now.tv_nsec - start_time.tv_nsec) * 1e-9;
+
+            return double(now.tv_sec - start_time.tv_sec) + 
+                (double(now.tv_nsec - start_time.tv_nsec) * 1e-9);
+        }
+
+        double elapsed_max() const   // return estimated maximum value for elapsed()
+        {
+            return double((std::numeric_limits<time_t>::max)() - start_time.tv_sec); 
+        }
+
+        double elapsed_min() const            // return minimum value for elapsed()
+        { 
+            timespec resolution;
+            if (-1 == clock_getres(CLOCK_REALTIME, &resolution))
+                boost::throw_exception(std::runtime_error("Couldn't get resolution"));
+            return double(resolution.tv_sec + resolution.tv_nsec * 1e-9); 
+        }
+
+    private:
+        timespec start_time;
+    }; 
+
+} // xml
+} // archive
+} // boost
+
+#else   // _POSIX_THREAD_CPUTIME > 0
+
+#include <boost/timer.hpp>
+
+// availability of high performance timers must be checked at runtime
+namespace boost {
+namespace archive {
+namespace xml {
+    ///////////////////////////////////////////////////////////////////////////////
+    //
+    //  high_resolution_timer 
+    //      A timer object measures elapsed time.
+    //
+    ///////////////////////////////////////////////////////////////////////////////
+    class high_resolution_timer
+    {
+    public:
+        high_resolution_timer() 
+          : use_backup(sysconf(_SC_THREAD_CPUTIME) <= 0)
+        {
+            if (!use_backup) {
+                start_time.tv_sec = 0;
+                start_time.tv_nsec = 0;
+            }
+            restart(); 
+        } 
+
+        high_resolution_timer(double t) 
+          : use_backup(sysconf(_SC_THREAD_CPUTIME) <= 0)
+        {
+            if (!use_backup) {
+                start_time.tv_sec = time_t(t);
+                start_time.tv_nsec = (t - start_time.tv_sec) * 1e9;
+            }
+        }
+        
+        high_resolution_timer(high_resolution_timer const& rhs) 
+          : use_backup(sysconf(_SC_THREAD_CPUTIME) <= 0),
+            start_time(rhs.start_time)
+        {
+        } 
+
+        static double now()
+        {
+            if (sysconf(_SC_THREAD_CPUTIME) <= 0)
+                return double(std::clock());
+
+            timespec now;
+            if (-1 == clock_gettime(CLOCK_REALTIME, &now))
+                boost::throw_exception(std::runtime_error("Couldn't get current time"));
+            return double(now.tv_sec) + double(now.tv_nsec) * 1e-9;
+        }
+
+        void restart() 
+        { 
+            if (use_backup)
+                start_time_backup.restart();
+            else if (-1 == clock_gettime(CLOCK_REALTIME, &start_time))
+                boost::throw_exception(std::runtime_error("Couldn't initialize start_time"));
+        } 
+        double elapsed() const                  // return elapsed time in seconds
+        { 
+            if (use_backup)
+                return start_time_backup.elapsed();
+
+            timespec now;
+            if (-1 == clock_gettime(CLOCK_REALTIME, &now))
+                boost::throw_exception(std::runtime_error("Couldn't get current time"));
+
+            if (now.tv_sec == start_time.tv_sec)
+                return double(now.tv_nsec - start_time.tv_nsec) * 1e-9;
+                
+            return double(now.tv_sec - start_time.tv_sec) + 
+                (double(now.tv_nsec - start_time.tv_nsec) * 1e-9);
+        }
+
+        double elapsed_max() const   // return estimated maximum value for elapsed()
+        {
+            if (use_backup)
+                start_time_backup.elapsed_max();
+
+            return double((std::numeric_limits<time_t>::max)() - start_time.tv_sec); 
+        }
+
+        double elapsed_min() const            // return minimum value for elapsed()
+        { 
+            if (use_backup)
+                start_time_backup.elapsed_min();
+
+            timespec resolution;
+            if (-1 == clock_getres(CLOCK_REALTIME, &resolution))
+                boost::throw_exception(std::runtime_error("Couldn't get resolution"));
+            return double(resolution.tv_sec + resolution.tv_nsec * 1e-9); 
+        }
+
+    private:
+        bool use_backup;
+        timespec start_time;
+        boost::timer start_time_backup;
+    }; 
+
+} // xml
+} // archive
+} // boost
+
+#endif  // _POSIX_THREAD_CPUTIME > 0
+
+#else   //  !defined(BOOST_WINDOWS) && (!defined(_POSIX_TIMERS)
+        //      || _POSIX_TIMERS <= 0
+        //      || !defined(_POSIX_THREAD_CPUTIME)
+        //      || _POSIX_THREAD_CPUTIME <= 0)
+
+#if defined(BOOST_HAS_GETTIMEOFDAY)
+
+// For platforms that do not support _POSIX_TIMERS but do have
+// GETTIMEOFDAY, which is still preferable to std::clock()
+#include <sys/time.h>
+
+namespace boost {
+namespace archive {
+namespace xml {
+
+    ///////////////////////////////////////////////////////////////////////////
+    //
+    //  high_resolution_timer 
+    //      A timer object measures elapsed time.
+    //
+    //  Implemented with gettimeofday() for platforms that support it,
+    //  such as Darwin (OS X) but do not support the previous options.
+    //
+    //  Copyright (c) 2009 Edward Grace
+    //
+    ///////////////////////////////////////////////////////////////////////////
+    class high_resolution_timer
+    {
+    private:
+        template <typename U>
+        static inline double unsigned_diff(const U &a, const U &b)
+        {
+            if (a > b)
+                return static_cast<double>(a-b);
+            return -static_cast<double>(b-a);
+        }
+
+        // @brief Return the difference between two timeval types.
+        // 
+        // @param t1 The most recent timeval.
+        // @param t0 The historical timeval.
+        // 
+        // @return The difference between the two in seconds.
+        double elapsed(const timeval &t1, const timeval &t0) const
+        { 
+            if (t1.tv_sec == t0.tv_sec)
+                return unsigned_diff(t1.tv_usec,t0.tv_usec) * 1e-6;
+
+            // We do it this way as the result of the difference of the
+            // microseconds can be negative if the clock is implemented so
+            // that the seconds timer increases in large steps.
+            //
+            // Naive subtraction of the unsigned types and conversion to
+            // double can wreak havoc!
+            return unsigned_diff(t1.tv_sec,t0.tv_sec) + 
+                unsigned_diff(t1.tv_usec,t0.tv_usec) * 1e-6; 
+        }
+
+    public:
+        high_resolution_timer() 
+        {
+            start_time.tv_sec = 0;
+            start_time.tv_usec = 0;
+
+            restart(); 
+        } 
+
+        high_resolution_timer(double t) 
+        {
+            start_time.tv_sec = time_t(t);
+            start_time.tv_usec = (t - start_time.tv_sec) * 1e6;
+        }
+
+        high_resolution_timer(high_resolution_timer const& rhs) 
+          : start_time(rhs.start_time)
+        {
+        } 
+
+        static double now()
+        {
+            // Under some implementations gettimeofday() will always
+            // return zero. If it returns anything else however then
+            // we accept this as evidence of an error.  Note we are
+            // not assuming that -1 explicitly indicates the error
+            // condition, just that non zero is indicative of the
+            // error.
+            timeval now;
+            if (gettimeofday(&now, NULL))
+                boost::throw_exception(std::runtime_error("Couldn't get current time"));
+            return double(now.tv_sec) + double(now.tv_usec) * 1e-6;
+        }
+
+        void restart() 
+        { 
+            if (gettimeofday(&start_time, NULL))
+                boost::throw_exception(std::runtime_error("Couldn't initialize start_time"));
+        } 
+
+        double elapsed() const                  // return elapsed time in seconds
+        { 
+            timeval now;
+            if (gettimeofday(&now, NULL))
+                boost::throw_exception(std::runtime_error("Couldn't get current time"));
+            return elapsed(now,start_time);
+        }
+
+        double elapsed_max() const   // return estimated maximum value for elapsed()
+        {
+            return double((std::numeric_limits<time_t>::max)() - start_time.tv_sec); 
+        }
+
+        double elapsed_min() const            // return minimum value for elapsed()
+        { 
+            // On systems without an explicit clock_getres or similar
+            // we can only estimate an upper bound on the resolution
+            // by repeatedly calling the gettimeofday function.  This
+            // is often likely to be indicative of the true
+            // resolution.
+            timeval t0, t1;
+            double delta(0);
+
+            if (gettimeofday(&t0, NULL)) 
+                boost::throw_exception(std::runtime_error("Couldn't get resolution."));
+
+            // Spin around in a tight loop until we observe a change
+            // in the reported timer value.
+            do {
+                if (gettimeofday(&t1, NULL)) 
+                    boost::throw_exception(std::runtime_error("Couldn't get resolution."));
+                delta = elapsed(t1, t0);
+            } while (delta <= 0.0);
+
+            return delta;
+        }
+
+    private:
+        timeval start_time;
+    }; 
+
+} // xml
+} // archive
+} // boost
+
+#else // BOOST_HAS_GETTIMEOFDAY
+
+//  For platforms other than Windows or Linux, or not implementing gettimeofday
+//  simply fall back to boost::timer
+#include <boost/timer.hpp>
+
+namespace boost {
+namespace archive {
+namespace xml {
+
+    struct high_resolution_timer
+        : boost::timer
+    {
+        static double now()
+        {
+            return double(std::clock());
+        }
+    };
+
+} // xml
+} // archive
+} // boost
+ 
+
+#endif
+
+#endif
+
+#endif  // HIGH_RESOLUTION_TIMER_AUG_14_2009_0425PM
+
+//
+// $Log: high_resolution_timer.hpp,v $
+// Revision 1.4  2009/08/14 15:28:10  graceej
+// * It is entirely possible for the updating clock to increment the
+// * seconds and *decrement* the microseconds field.  Consequently
+// * when subtracting these unsigned microseconds fields a wrap-around
+// * error can occur.  For this reason elapsed(t1, t0) is used in a
+// * similar maner to cycle.h this preserves the sign of the
+// * difference.
+//