Squashed 'third_party/boostorg/type_traits/' content from commit 059ed88

Change-Id: I222c604dfa1db194bf53bc6aa1152fb16e83ce06
git-subtree-dir: third_party/boostorg/type_traits
git-subtree-split: 059ed8839da3fecd1e8b62cdc11be006f6346b5e
diff --git a/examples/copy_example.cpp b/examples/copy_example.cpp
new file mode 100644
index 0000000..2ba60a8
--- /dev/null
+++ b/examples/copy_example.cpp
@@ -0,0 +1,197 @@
+
+/*
+ *
+ * (C) Copyright John Maddock 1999-2005. 
+ * Use, modification and distribution are subject to 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)
+ *
+ * This file provides some example of type_traits usage -
+ * by "optimising" various algorithms:
+ *
+ * opt::copy - optimised for trivial copy (cf std::copy)
+ *
+ */
+
+#include <iostream>
+#include <typeinfo>
+#include <algorithm>
+#include <iterator>
+#include <memory>
+
+#include <boost/test/included/prg_exec_monitor.hpp>
+#include <boost/timer.hpp>
+#include <boost/type_traits.hpp>
+
+using std::cout;
+using std::endl;
+using std::cin;
+
+namespace opt{
+
+//
+// opt::copy
+// same semantics as std::copy
+// calls memcpy where appropriate.
+//
+
+namespace detail{
+
+template<typename I1, typename I2, bool b>
+I2 copy_imp(I1 first, I1 last, I2 out, const boost::integral_constant<bool, b>&)
+{
+   while(first != last)
+   {
+      *out = *first;
+      ++out;
+      ++first;
+   }
+   return out;
+}
+
+template<typename T>
+T* copy_imp(const T* first, const T* last, T* out, const boost::true_type&)
+{
+   memmove(out, first, (last-first)*sizeof(T));
+   return out+(last-first);
+}
+
+
+}
+
+template<typename I1, typename I2>
+inline I2 copy(I1 first, I1 last, I2 out)
+{
+   //
+   // We can copy with memcpy if T has a trivial assignment operator,
+   // and if the iterator arguments are actually pointers (this last
+   // requirement we detect with overload resolution):
+   //
+   typedef typename std::iterator_traits<I1>::value_type value_type;
+   return detail::copy_imp(first, last, out, boost::has_trivial_assign<value_type>());
+}
+
+}   // namespace opt
+
+namespace non_opt
+{
+
+template<typename I1, typename I2>
+inline I2 copy(I1 first, I1 last, I2 out)
+{
+   return opt::detail::copy_imp(first, last, out, boost::false_type());
+}
+
+}
+
+//
+// define some global data:
+//
+const int array_size = 1000;
+int i_array_[array_size] = {0,};
+const int ci_array_[array_size] = {0,};
+char c_array_[array_size] = {0,};
+const char cc_array_[array_size] = { 0,};
+//
+// since arrays aren't iterators we define a set of pointer
+// aliases into the arrays (otherwise the compiler is entitled
+// to deduce the type passed to the template functions as
+// T (&)[N] rather than T*).
+int* i_array = i_array_;
+const int* ci_array = ci_array_;
+char* c_array = c_array_;
+const char* cc_array = cc_array_;
+
+const int iter_count = 1000000;
+
+int cpp_main(int argc, char* argv[])
+{
+   boost::timer t;
+   double result;
+   int i;
+   cout << "Measuring times in micro-seconds per 1000 elements processed" << endl << endl;
+   cout << "testing copy...\n"
+   "[Some standard library versions may already perform this optimisation.]" << endl;
+   
+   // cache load:
+   opt::copy(ci_array, ci_array + array_size, i_array);
+
+   // time optimised version:
+   t.restart();
+   for(i = 0; i < iter_count; ++i)
+   {
+      opt::copy(ci_array, ci_array + array_size, i_array);
+   }
+   result = t.elapsed();
+   cout << "opt::copy<const int*, int*>: " << result << endl;
+
+   // cache load:
+   non_opt::copy(ci_array, ci_array + array_size, i_array);
+
+   // time non-optimised version:
+   t.restart();
+   for(i = 0; i < iter_count; ++i)
+   {
+      non_opt::copy(ci_array, ci_array + array_size, i_array);
+   }
+   result = t.elapsed();
+   cout << "non_opt::copy<const int*, int*>: " << result << endl;
+
+   // cache load:
+   std::copy(ci_array, ci_array + array_size, i_array);
+
+   // time standard version:
+   t.restart();
+   for(i = 0; i < iter_count; ++i)
+   {
+      std::copy(ci_array, ci_array + array_size, i_array);
+   }
+   result = t.elapsed();
+   cout << "std::copy<const int*, int*>: " << result << endl;
+
+   // cache load:
+   opt::copy(cc_array, cc_array + array_size, c_array);
+
+   // time optimised version:
+   t.restart();
+   for(i = 0; i < iter_count; ++i)
+   {
+      opt::copy(cc_array, cc_array + array_size, c_array);
+   }
+   result = t.elapsed();
+   cout << "opt::copy<const char*, char*>: " << result << endl;
+
+   // cache load:
+   non_opt::copy(cc_array, cc_array + array_size, c_array);
+
+   // time optimised version:
+   t.restart();
+   for(i = 0; i < iter_count; ++i)
+   {
+      non_opt::copy(cc_array, cc_array + array_size, c_array);
+   }
+   result = t.elapsed();
+   cout << "non_opt::copy<const char*, char*>: " << result << endl;
+
+   // cache load:
+   std::copy(cc_array, cc_array + array_size, c_array);
+
+   // time standard version:
+   t.restart();
+   for(i = 0; i < iter_count; ++i)
+   {
+      std::copy(cc_array, cc_array + array_size, c_array);
+   }
+   result = t.elapsed();
+   cout << "std::copy<const char*, char*>: " << result << endl;
+
+   return 0;
+}
+
+
+
+
+
+
+
+
diff --git a/examples/fill_example.cpp b/examples/fill_example.cpp
new file mode 100644
index 0000000..3e3af06
--- /dev/null
+++ b/examples/fill_example.cpp
@@ -0,0 +1,200 @@
+
+/*
+ *
+ * (C) Copyright John Maddock 1999-2005. 
+ * Use, modification and distribution are subject to 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)
+ *
+ * This file provides some example of type_traits usage -
+ * by "optimising" various algorithms:
+ *
+ * opt::fill - optimised for trivial copy/small types (cf std::fill)
+ *
+ */
+
+#include <iostream>
+#include <typeinfo>
+#include <algorithm>
+#include <iterator>
+#include <memory>
+#include <cstring>
+
+#include <boost/test/included/prg_exec_monitor.hpp>
+#include <boost/timer.hpp>
+#include <boost/type_traits.hpp>
+
+#if defined(BOOST_NO_STDC_NAMESPACE) || (defined(std) && defined(__SGI_STL_PORT))
+namespace std{ using :: memset; }
+#endif
+
+using std::cout;
+using std::endl;
+using std::cin;
+
+namespace opt{
+//
+// fill
+// same as std::fill, but uses memset where appropriate
+//
+namespace detail{
+
+template <typename I, typename T, bool b>
+void do_fill(I first, I last, const T& val, const boost::integral_constant<bool, b>&)
+{
+   while(first != last)
+   {
+      *first = val;
+      ++first;
+   }
+}
+
+template <typename T>
+void do_fill(T* first, T* last, const T& val, const boost::true_type&)
+{
+   std::memset(first, val, last-first);
+}
+
+}
+
+template <class I, class T>
+inline void fill(I first, I last, const T& val)
+{
+   //
+   // We can do an optimised fill if T has a trivial assignment 
+   // operator and if it's size is one:
+   //
+   typedef boost::integral_constant<bool, 
+      ::boost::has_trivial_assign<T>::value && (sizeof(T) == 1)> truth_type;
+   detail::do_fill(first, last, val, truth_type());
+}
+
+}   // namespace opt
+
+namespace non_opt{
+
+template <class I, class T>
+inline void fill(I first, I last, const T& val)
+{
+   opt::detail::do_fill(first, last, val, boost::false_type());
+}
+
+}
+
+//
+// define some global data:
+//
+const int array_size = 1000;
+int i_array_[array_size] = {0,};
+const int ci_array_[array_size] = {0,};
+char c_array_[array_size] = {0,};
+const char cc_array_[array_size] = { 0,};
+//
+// since arrays aren't iterators we define a set of pointer
+// aliases into the arrays (otherwise the compiler is entitled
+// to deduce the type passed to the template functions as
+// T (&)[N] rather than T*).
+int* i_array = i_array_;
+const int* ci_array = ci_array_;
+char* c_array = c_array_;
+const char* cc_array = cc_array_;
+
+const int iter_count = 1000000;
+
+int cpp_main(int argc, char* argv[])
+{
+   boost::timer t;
+   double result;
+   int i;
+   //
+   // test destroy_array,
+   // compare destruction time of an array of ints
+   // with unoptimised form.
+   //
+   cout << "Measuring times in micro-seconds per 1000 elements processed" << endl << endl;
+
+   cout << "testing fill(char)...\n"
+   "[Some standard library versions may already perform this optimisation.]" << endl;
+
+   // cache load:
+   opt::fill(c_array, c_array + array_size, (char)3);
+
+   // time optimised version:
+   t.restart();
+   for(i = 0; i < iter_count; ++i)
+   {
+      opt::fill(c_array, c_array + array_size, (char)3);
+   }
+   result = t.elapsed();
+   cout << "opt::fill<char*, char>: " << result << endl;
+
+   // cache load:
+   non_opt::fill(c_array, c_array + array_size, (char)3);
+
+   // time optimised version:
+   t.restart();
+   for(i = 0; i < iter_count; ++i)
+   {
+      non_opt::fill(c_array, c_array + array_size, (char)3);
+   }
+   result = t.elapsed();
+   cout << "non_opt::fill<char*, char>: " << result << endl;
+
+   // cache load:
+   std::fill(c_array, c_array + array_size, (char)3);
+
+   // time standard version:
+   t.restart();
+   for(i = 0; i < iter_count; ++i)
+   {
+      std::fill(c_array, c_array + array_size, (char)3);
+   }
+   result = t.elapsed();
+   cout << "std::fill<char*, char>: " << result << endl << endl;
+
+   cout << "testing fill(int)...\n" << endl;
+
+   // cache load:
+   opt::fill(i_array, i_array + array_size, 3);
+
+   // timer optimised version:
+   t.restart();
+   for(i = 0; i < iter_count; ++i)
+   {
+      opt::fill(i_array, i_array + array_size, 3);
+   }
+   result = t.elapsed();
+   cout << "opt::fill<int*, int>: " << result << endl;
+
+   // cache load:
+   non_opt::fill(i_array, i_array + array_size, 3);
+
+   // timer optimised version:
+   t.restart();
+   for(i = 0; i < iter_count; ++i)
+   {
+      non_opt::fill(i_array, i_array + array_size, 3);
+   }
+   result = t.elapsed();
+   cout << "non_opt::fill<int*, int>: " << result << endl;
+
+   // cache load:
+   std::fill(i_array, i_array + array_size, 3);
+
+   // time standard version:
+   t.restart();
+   for(i = 0; i < iter_count; ++i)
+   {
+      std::fill(i_array, i_array + array_size, 3);
+   }
+   result = t.elapsed();
+   cout << "std::fill<int*, int>: " << result << endl << endl;
+
+   return 0;
+}
+
+
+
+
+
+
diff --git a/examples/iter_swap_example.cpp b/examples/iter_swap_example.cpp
new file mode 100644
index 0000000..ea04747
--- /dev/null
+++ b/examples/iter_swap_example.cpp
@@ -0,0 +1,97 @@
+
+/*
+ *
+ * (C) Copyright John Maddock 1999-2005. 
+ * Use, modification and distribution are subject to 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)
+ *
+ * This file provides some example of type_traits usage -
+ * by "optimising" various algorithms:
+ *
+ * opt::iter_swap - uses type_traits to determine whether the iterator is a proxy
+ *                  in which case it uses a "safe" approach, otherwise calls swap
+ *                  on the assumption that swap may be specialised for the pointed-to type.
+ *
+ */
+
+#include <iostream>
+#include <typeinfo>
+#include <algorithm>
+#include <iterator>
+#include <vector>
+#include <memory>
+
+#include <boost/test/included/prg_exec_monitor.hpp>
+#include <boost/type_traits.hpp>
+
+using std::cout;
+using std::endl;
+using std::cin;
+
+namespace opt{
+
+//
+// iter_swap:
+// tests whether iterator is a proxy iterator or not, and
+// uses optimal form accordingly:
+//
+namespace detail{
+
+template <typename I>
+static void do_swap(I one, I two, const boost::false_type&)
+{
+   typedef typename std::iterator_traits<I>::value_type v_t;
+   v_t v = *one;
+   *one = *two;
+   *two = v;
+}
+template <typename I>
+static void do_swap(I one, I two, const boost::true_type&)
+{
+   using std::swap;
+   swap(*one, *two);
+}
+
+}
+
+template <typename I1, typename I2>
+inline void iter_swap(I1 one, I2 two)
+{
+   //
+   // See is both arguments are non-proxying iterators, 
+   // and if both iterator the same type:
+   //
+   typedef typename std::iterator_traits<I1>::reference r1_t;
+   typedef typename std::iterator_traits<I2>::reference r2_t;
+
+   typedef boost::integral_constant<bool,
+      ::boost::is_reference<r1_t>::value
+      && ::boost::is_reference<r2_t>::value
+      && ::boost::is_same<r1_t, r2_t>::value> truth_type;
+
+   detail::do_swap(one, two, truth_type());
+}
+
+
+};   // namespace opt
+
+int cpp_main(int argc, char* argv[])
+{
+   //
+   // testing iter_swap
+   // really just a check that it does in fact compile...
+   std::vector<int> v1;
+   v1.push_back(0);
+   v1.push_back(1);
+   std::vector<bool> v2;
+   v2.push_back(0);
+   v2.push_back(1);
+   opt::iter_swap(v1.begin(), v1.begin()+1);
+   opt::iter_swap(v2.begin(), v2.begin()+1);
+
+   return 0;
+}
+
+
+
diff --git a/examples/trivial_destructor_example.cpp b/examples/trivial_destructor_example.cpp
new file mode 100644
index 0000000..49ee63a
--- /dev/null
+++ b/examples/trivial_destructor_example.cpp
@@ -0,0 +1,153 @@
+
+/*
+ *
+ * (C) Copyright John Maddock 1999-2005. 
+ * Use, modification and distribution are subject to 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)
+ *
+ * This file provides some example of type_traits usage -
+ * by "optimising" various algorithms:
+ *
+ * opt::destroy_array - an example of optimisation based upon omitted destructor calls
+ *
+ */
+
+
+#include <iostream>
+#include <boost/test/included/prg_exec_monitor.hpp>
+#include <boost/timer.hpp>
+#include <boost/type_traits.hpp>
+
+using std::cout;
+using std::endl;
+using std::cin;
+
+namespace opt{
+
+//
+// algorithm destroy_array:
+// The reverse of std::unitialized_copy, takes a block of
+// initialized memory and calls destructors on all objects therein.
+//
+
+namespace detail{
+
+template <class T>
+void do_destroy_array(T* first, T* last, const boost::false_type&)
+{
+   while(first != last)
+   {
+      first->~T();
+      ++first;
+   }
+}
+
+template <class T>
+inline void do_destroy_array(T* first, T* last, const boost::true_type&)
+{
+}
+
+} // namespace detail
+
+template <class T>
+inline void destroy_array(T* p1, T* p2)
+{
+   detail::do_destroy_array(p1, p2, ::boost::has_trivial_destructor<T>());
+}
+
+//
+// unoptimised versions of destroy_array:
+//
+template <class T>
+void destroy_array1(T* first, T* last)
+{
+   while(first != last)
+   {
+      first->~T();
+      ++first;
+   }
+}
+template <class T>
+void destroy_array2(T* first, T* last)
+{
+   for(; first != last; ++first) first->~T();
+}
+
+} // namespace opt
+
+//
+// define some global data:
+//
+const int array_size = 1000;
+int i_array[array_size] = {0,};
+const int ci_array[array_size] = {0,};
+char c_array[array_size] = {0,};
+const char cc_array[array_size] = { 0,};
+
+const int iter_count = 1000000;
+
+
+int cpp_main(int argc, char* argv[])
+{
+   boost::timer t;
+   double result;
+   int i;
+   //
+   // test destroy_array,
+   // compare destruction time of an array of ints
+   // with unoptimised form.
+   //
+   cout << "Measuring times in micro-seconds per 1000 elements processed" << endl << endl;
+   cout << "testing destroy_array...\n"
+    "[Some compilers may be able to optimise the \"unoptimised\"\n versions as well as type_traits does.]" << endl;
+   
+   // cache load:
+   opt::destroy_array(i_array, i_array + array_size);
+
+   // time optimised version:
+   t.restart();
+   for(i = 0; i < iter_count; ++i)
+   {
+      opt::destroy_array(i_array, i_array + array_size);
+   }
+   result = t.elapsed();
+   cout << "destroy_array<int>: " << result << endl;
+
+   // cache load:
+   opt::destroy_array1(i_array, i_array + array_size);
+
+   // time unoptimised version #1:
+   t.restart();
+   for(i = 0; i < iter_count; ++i)
+   {
+      opt::destroy_array1(i_array, i_array + array_size);
+   }
+   result = t.elapsed();
+   cout << "destroy_array<int>(unoptimised#1): " << result << endl;
+
+   // cache load:
+   opt::destroy_array2(i_array, i_array + array_size);
+
+   // time unoptimised version #2:
+   t.restart();
+   for(i = 0; i < iter_count; ++i)
+   {
+      opt::destroy_array2(i_array, i_array + array_size);
+   }
+   result = t.elapsed();
+   cout << "destroy_array<int>(unoptimised#2): " << result << endl << endl;
+
+   return 0;
+}
+
+
+
+
+
+
+
+
+
+
+