Squashed 'third_party/boostorg/optional/' content from commit 155ad59

Change-Id: I4ad7a1e7b295a6136c5a0d7b6c11700e76b939b5
git-subtree-dir: third_party/boostorg/optional
git-subtree-split: 155ad5911e5683cc87d34363f8304b60a30a8345
diff --git a/include/boost/optional/detail/experimental_traits.hpp b/include/boost/optional/detail/experimental_traits.hpp
new file mode 100644
index 0000000..b51f5f1
--- /dev/null
+++ b/include/boost/optional/detail/experimental_traits.hpp
@@ -0,0 +1,104 @@
+// Copyright (C) 2017 Andrzej Krzemienski.
+//
+// Use, modification, and distribution is 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)
+//
+// See http://www.boost.org/libs/optional for documentation.
+//
+// You are welcome to contact the author at:
+//  akrzemi1@gmail.com
+
+#ifndef BOOST_OPTIONAL_DETAIL_EXPERIMENTAL_TRAITS_04NOV2017_HPP
+#define BOOST_OPTIONAL_DETAIL_EXPERIMENTAL_TRAITS_04NOV2017_HPP
+
+#include <boost/config.hpp>
+#include <boost/detail/workaround.hpp>
+#include <boost/predef.h>
+#include <boost/type_traits.hpp>
+  
+// The condition to use POD implementation
+
+#ifdef BOOST_OPTIONAL_CONFIG_NO_POD_SPEC
+# define BOOST_OPTIONAL_DETAIL_NO_SPEC_FOR_TRIVIAL_TYPES
+#elif defined BOOST_OPTIONAL_CONFIG_NO_SPEC_FOR_TRIVIAL_TYPES
+# define BOOST_OPTIONAL_DETAIL_NO_SPEC_FOR_TRIVIAL_TYPES
+#elif !defined BOOST_HAS_TRIVIAL_CONSTRUCTOR
+# define BOOST_OPTIONAL_DETAIL_NO_SPEC_FOR_TRIVIAL_TYPES
+#elif !defined BOOST_HAS_TRIVIAL_MOVE_ASSIGN
+# define BOOST_OPTIONAL_DETAIL_NO_SPEC_FOR_TRIVIAL_TYPES
+#elif !defined BOOST_HAS_TRIVIAL_MOVE_CONSTRUCTOR
+# define BOOST_OPTIONAL_DETAIL_NO_SPEC_FOR_TRIVIAL_TYPES
+#elif !defined BOOST_HAS_TRIVIAL_COPY
+# define BOOST_OPTIONAL_DETAIL_NO_SPEC_FOR_TRIVIAL_TYPES
+#elif !defined BOOST_HAS_TRIVIAL_ASSIGN
+# define BOOST_OPTIONAL_DETAIL_NO_SPEC_FOR_TRIVIAL_TYPES
+#elif !defined BOOST_HAS_TRIVIAL_DESTRUCTOR
+# define BOOST_OPTIONAL_DETAIL_NO_SPEC_FOR_TRIVIAL_TYPES
+#elif BOOST_WORKAROUND(BOOST_GCC, < 50000)
+# define BOOST_OPTIONAL_DETAIL_NO_SPEC_FOR_TRIVIAL_TYPES
+#endif
+
+// GCC 5 or higher, or clang with libc++ or clang with libstdc++ 5 or higher
+#if __cplusplus >= 201103L
+#  if BOOST_WORKAROUND(BOOST_GCC, >= 50000)
+#    define BOOST_OPTIONAL_DETAIL_USE_STD_TYPE_TRAITS
+#  elif (defined BOOST_CLANG)
+#    if BOOST_LIB_STD_CXX > 0
+#      define BOOST_OPTIONAL_DETAIL_USE_STD_TYPE_TRAITS
+#    elif BOOST_LIB_STD_GNU >= 441200023 && BOOST_LIB_STD_GNU != 450600023 && BOOST_LIB_STD_GNU != 450600026 && BOOST_LIB_STD_GNU != 460800003 && BOOST_LIB_STD_GNU != 450400026 && BOOST_LIB_STD_GNU != 460700026
+#      define BOOST_OPTIONAL_DETAIL_USE_STD_TYPE_TRAITS
+#    endif
+#  endif
+#endif  
+
+
+#ifndef BOOST_OPTIONAL_DETAIL_USE_STD_TYPE_TRAITS
+#  define BOOST_OPTIONAL_DETAIL_HAS_TRIVIAL_CTOR(T) BOOST_HAS_TRIVIAL_CONSTRUCTOR(T)
+#else
+#  include <type_traits>
+#  define BOOST_OPTIONAL_DETAIL_HAS_TRIVIAL_CTOR(T) std::is_trivially_default_constructible<T>::value
+#endif
+  
+  
+namespace boost { namespace optional_detail {
+  
+#ifndef BOOST_OPTIONAL_DETAIL_NO_SPEC_FOR_TRIVIAL_TYPES
+template <typename T>
+struct is_type_trivially_copyable
+  : boost::conditional<(boost::has_trivial_copy_constructor<T>::value &&
+                        boost::has_trivial_move_constructor<T>::value &&
+                        boost::has_trivial_destructor<T>::value &&
+                        boost::has_trivial_move_assign<T>::value &&
+                        boost::has_trivial_assign<T>::value),
+                        boost::true_type, boost::false_type>::type
+{};
+#else
+template <typename T>
+struct is_type_trivially_copyable
+: boost::conditional<(boost::is_scalar<T>::value && !boost::is_const<T>::value && !boost::is_volatile<T>::value),
+                     boost::true_type, boost::false_type>::type
+{};
+#endif
+
+
+
+#ifndef BOOST_OPTIONAL_DETAIL_NO_SPEC_FOR_TRIVIAL_TYPES  
+template <typename T>
+struct optional_uses_direct_storage_for_
+  : boost::conditional< (is_type_trivially_copyable<T>::value && BOOST_OPTIONAL_DETAIL_HAS_TRIVIAL_CTOR(T)) ||
+                        (boost::is_scalar<T>::value && !boost::is_const<T>::value && !boost::is_volatile<T>::value)
+                      , boost::true_type, boost::false_type>::type
+{};
+#else
+template <typename T>
+struct optional_uses_direct_storage_for_
+  : boost::conditional<(boost::is_scalar<T>::value && !boost::is_const<T>::value && !boost::is_volatile<T>::value)
+                      , boost::true_type, boost::false_type>::type
+{};
+#endif
+
+
+}} // boost::optional_detail
+
+#endif