Merge to upstream r225300.
Change-Id: I2b23715db9ac129ff80aa78ad5824db0a4d6fbb3
This commit is contained in:
@@ -27,7 +27,15 @@ MACRO_ENSURE_OUT_OF_SOURCE_BUILD(
|
||||
)
|
||||
|
||||
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
|
||||
set(LIBCXX_LIBDIR_SUFFIX "" CACHE STRING
|
||||
"Define suffix of library directory name (32/64)")
|
||||
|
||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib${LIBCXX_LIBDIR_SUFFIX})
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib${LIBCXX_LIBDIR_SUFFIX})
|
||||
|
||||
set(LIBCXX_BUILT_STANDALONE 1)
|
||||
else()
|
||||
set(LIBCXX_LIBDIR_SUFFIX ${LLVM_LIBDIR_SUFFIX})
|
||||
endif()
|
||||
|
||||
#===============================================================================
|
||||
@@ -42,6 +50,12 @@ option(LIBCXX_ENABLE_PEDANTIC "Compile with pedantic enabled." ON)
|
||||
option(LIBCXX_ENABLE_WERROR "Fail and stop if a warning is triggered." OFF)
|
||||
option(LIBCXX_ENABLE_CXX1Y "Enable -std=c++1y and use of c++1y language features if the compiler supports it." OFF)
|
||||
option(LIBCXX_ENABLE_SHARED "Build libc++ as a shared library." ON)
|
||||
option(LIBCXX_ENABLE_THREADS "Build libc++ with support for threads." ON)
|
||||
option(LIBCXX_BUILD_32_BITS "Build 32 bit libc++" OFF)
|
||||
option(LIBCXX_ENABLE_MONOTONIC_CLOCK
|
||||
"Build libc++ with support for a monotonic clock.
|
||||
This option may only be used when LIBCXX_ENABLE_THREADS=OFF." ON)
|
||||
option(LIBCXX_INSTALL_HEADERS "Install the libc++ headers." ON)
|
||||
option(LIBCXX_INSTALL_SUPPORT_HEADERS "Install libc++ support headers." ON)
|
||||
if (LIBCXX_BUILT_STANDALONE)
|
||||
set(LLVM_USE_SANITIZER "" CACHE STRING
|
||||
@@ -84,6 +98,10 @@ get_target_triple(LIBCXX_TARGET_TRIPLE
|
||||
)
|
||||
set(LIBCXX_TARGET_TRIPLE ${LIBCXX_TARGET_TRIPLE} CACHE STRING "Target triple.")
|
||||
|
||||
set(LIBCXX_COMPILER ${CMAKE_CXX_COMPILER})
|
||||
set(LIBCXX_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
set(LIBCXX_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR})
|
||||
set(LIBCXX_LIBRARY_DIR ${CMAKE_BINARY_DIR}/lib${LIBCXX_LIBDIR_SUFFIX})
|
||||
|
||||
# Declare libc++ configuration variables.
|
||||
# They are intended for use as follows:
|
||||
@@ -201,11 +219,31 @@ if (NOT LIBCXX_ENABLE_SHARED)
|
||||
list(APPEND LIBCXX_COMPILE_FLAGS -D_LIBCPP_BUILD_STATIC)
|
||||
endif()
|
||||
|
||||
if (CMAKE_SIZEOF_VOID_P EQUAL 8 AND NOT WIN32)
|
||||
if (LIBCXX_BUILD_32_BITS)
|
||||
message(STATUS "Building 32 bits executables and libraries.")
|
||||
list(APPEND LIBCXX_CXX_FLAGS "-m32")
|
||||
endif()
|
||||
elseif(LIBCXX_BUILD_32_BITS)
|
||||
message(FATAL_ERROR "LIBCXX_BUILD_32_BITS=ON is not supported on this platform.")
|
||||
endif()
|
||||
# This is the _ONLY_ place where add_definitions is called.
|
||||
if (MSVC)
|
||||
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
|
||||
endif()
|
||||
|
||||
# LIBCXX_ENABLE_THREADS configuration
|
||||
if (NOT LIBCXX_ENABLE_THREADS)
|
||||
add_definitions(-D_LIBCPP_HAS_NO_THREADS)
|
||||
if (NOT LIBCXX_ENABLE_MONOTONIC_CLOCK)
|
||||
add_definitions(-D_LIBCPP_HAS_NO_MONOTONIC_CLOCK)
|
||||
endif()
|
||||
# Ensure LIBCXX_ENABLE_MONOTONIC_CLOCK is set to ON.
|
||||
elseif(NOT LIBCXX_ENABLE_MONOTONIC_CLOCK)
|
||||
message(FATAL_ERROR "LIBCXX_ENABLE_MONOTONIC_CLOCK can only be set to OFF"
|
||||
" when LIBCXX_ENABLE_THREADS is also set to OFF.")
|
||||
endif()
|
||||
|
||||
# Configure for sanitizers. If LIBCXX_BUILT_STANDALONE then we have to do
|
||||
# the flag translation ourselves. Othewise LLVM's CMakeList.txt will handle it.
|
||||
if (LIBCXX_BUILT_STANDALONE)
|
||||
|
||||
@@ -14,9 +14,11 @@ file(COPY .
|
||||
${LIBCXX_HEADER_PATTERN}
|
||||
)
|
||||
|
||||
if (LIBCXX_INSTALL_HEADERS)
|
||||
install(DIRECTORY .
|
||||
DESTINATION include/c++/v1
|
||||
FILES_MATCHING
|
||||
${LIBCXX_HEADER_PATTERN}
|
||||
PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ
|
||||
)
|
||||
endif()
|
||||
|
||||
@@ -705,7 +705,7 @@ inline _LIBCPP_INLINE_VISIBILITY
|
||||
__bit_iterator<_Cp, false>
|
||||
move_backward(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result)
|
||||
{
|
||||
return _VSTD::copy(__first, __last, __result);
|
||||
return _VSTD::copy_backward(__first, __last, __result);
|
||||
}
|
||||
|
||||
// swap_ranges
|
||||
|
||||
@@ -110,6 +110,13 @@
|
||||
# endif
|
||||
#endif // __sun__
|
||||
|
||||
#if defined(__native_client__)
|
||||
// NaCl's sandbox (which PNaCl also runs in) doesn't allow filesystem access,
|
||||
// including accesses to the special files under /dev. C++11's
|
||||
// std::random_device is instead exposed through a NaCl syscall.
|
||||
# define _LIBCPP_USING_NACL_RANDOM
|
||||
#endif // defined(__native_client__)
|
||||
|
||||
#if !defined(_LIBCPP_LITTLE_ENDIAN) || !defined(_LIBCPP_BIG_ENDIAN)
|
||||
# include <endian.h>
|
||||
# if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
@@ -690,4 +697,9 @@ extern "C" void __sanitizer_annotate_contiguous_container(
|
||||
# define _LIBCPP_WEAK __attribute__((__weak__))
|
||||
#endif
|
||||
|
||||
#if defined(_LIBCPP_HAS_NO_MONOTONIC_CLOCK) && !defined(_LIBCPP_HAS_NO_THREADS)
|
||||
# error _LIBCPP_HAS_NO_MONOTONIC_CLOCK may only be defined when \
|
||||
_LIBCPP_HAS_NO_THREADS is defined.
|
||||
#endif
|
||||
|
||||
#endif // _LIBCPP_CONFIG
|
||||
|
||||
@@ -29,8 +29,12 @@
|
||||
# if __ANDROID_API__ <= 20
|
||||
# include <support/android/locale_bionic.h>
|
||||
# endif
|
||||
#elif defined(__sun__)
|
||||
# include <support/solaris/xlocale.h>
|
||||
#elif defined(_NEWLIB_VERSION)
|
||||
# include <support/newlib/xlocale.h>
|
||||
#elif (defined(__GLIBC__) || defined(__APPLE__) || defined(__FreeBSD__) \
|
||||
|| defined(__sun__) || defined(__EMSCRIPTEN__) || defined(__IBMCPP__))
|
||||
|| defined(__EMSCRIPTEN__) || defined(__IBMCPP__))
|
||||
# include <xlocale.h>
|
||||
#endif // __GLIBC__ || __APPLE__ || __FreeBSD__ || __sun__ || __EMSCRIPTEN__ || __IBMCPP__
|
||||
|
||||
|
||||
@@ -16,131 +16,147 @@
|
||||
|
||||
// C++1y
|
||||
|
||||
#include <initializer_list>
|
||||
namespace std { namespace experimental { inline namespace fundamentals_v1 {
|
||||
|
||||
namespace std { namespace experimental {
|
||||
// 5.3, optional for object types
|
||||
template <class T> class optional;
|
||||
|
||||
// 5.4, In-place construction
|
||||
struct in_place_t{};
|
||||
constexpr in_place_t in_place{};
|
||||
|
||||
// 5.5, No-value state indicator
|
||||
struct nullopt_t{see below};
|
||||
constexpr nullopt_t nullopt(unspecified);
|
||||
|
||||
// 5.6, Class bad_optional_access
|
||||
class bad_optional_access;
|
||||
|
||||
// 5.7, Relational operators
|
||||
template <class T>
|
||||
constexpr bool operator==(const optional<T>&, const optional<T>&);
|
||||
template <class T>
|
||||
constexpr bool operator!=(const optional<T>&, const optional<T>&);
|
||||
template <class T>
|
||||
constexpr bool operator<(const optional<T>&, const optional<T>&);
|
||||
template <class T>
|
||||
constexpr bool operator>(const optional<T>&, const optional<T>&);
|
||||
template <class T>
|
||||
constexpr bool operator<=(const optional<T>&, const optional<T>&);
|
||||
template <class T>
|
||||
constexpr bool operator>=(const optional<T>&, const optional<T>&);
|
||||
|
||||
// 5.8, Comparison with nullopt
|
||||
template <class T> constexpr bool operator==(const optional<T>&, nullopt_t) noexcept;
|
||||
template <class T> constexpr bool operator==(nullopt_t, const optional<T>&) noexcept;
|
||||
template <class T> constexpr bool operator!=(const optional<T>&, nullopt_t) noexcept;
|
||||
template <class T> constexpr bool operator!=(nullopt_t, const optional<T>&) noexcept;
|
||||
template <class T> constexpr bool operator<(const optional<T>&, nullopt_t) noexcept;
|
||||
template <class T> constexpr bool operator<(nullopt_t, const optional<T>&) noexcept;
|
||||
template <class T> constexpr bool operator<=(const optional<T>&, nullopt_t) noexcept;
|
||||
template <class T> constexpr bool operator<=(nullopt_t, const optional<T>&) noexcept;
|
||||
template <class T> constexpr bool operator>(const optional<T>&, nullopt_t) noexcept;
|
||||
template <class T> constexpr bool operator>(nullopt_t, const optional<T>&) noexcept;
|
||||
template <class T> constexpr bool operator>=(const optional<T>&, nullopt_t) noexcept;
|
||||
template <class T> constexpr bool operator>=(nullopt_t, const optional<T>&) noexcept;
|
||||
|
||||
// 5.9, Comparison with T
|
||||
template <class T> constexpr bool operator==(const optional<T>&, const T&);
|
||||
template <class T> constexpr bool operator==(const T&, const optional<T>&);
|
||||
template <class T> constexpr bool operator!=(const optional<T>&, const T&);
|
||||
template <class T> constexpr bool operator!=(const T&, const optional<T>&);
|
||||
template <class T> constexpr bool operator<(const optional<T>&, const T&);
|
||||
template <class T> constexpr bool operator<(const T&, const optional<T>&);
|
||||
template <class T> constexpr bool operator<=(const optional<T>&, const T&);
|
||||
template <class T> constexpr bool operator<=(const T&, const optional<T>&);
|
||||
template <class T> constexpr bool operator>(const optional<T>&, const T&);
|
||||
template <class T> constexpr bool operator>(const T&, const optional<T>&);
|
||||
template <class T> constexpr bool operator>=(const optional<T>&, const T&);
|
||||
template <class T> constexpr bool operator>=(const T&, const optional<T>&);
|
||||
|
||||
// 5.10, Specialized algorithms
|
||||
template <class T> void swap(optional<T>&, optional<T>&) noexcept(see below);
|
||||
template <class T> constexpr optional<see below> make_optional(T&&);
|
||||
|
||||
// optional for object types
|
||||
template <class T>
|
||||
class optional
|
||||
{
|
||||
public:
|
||||
typedef T value_type;
|
||||
|
||||
// constructors
|
||||
// 5.3.1, Constructors
|
||||
constexpr optional() noexcept;
|
||||
constexpr optional(nullopt_t) noexcept;
|
||||
optional(const optional&);
|
||||
optional(optional&&) noexcept(is_nothrow_move_constructible<T>::value);
|
||||
optional(optional&&) noexcept(see below);
|
||||
constexpr optional(const T&);
|
||||
constexpr optional(T&&);
|
||||
template <class... Args> constexpr explicit optional(in_place_t, Args&&...);
|
||||
template <class U, class... Args>
|
||||
constexpr explicit optional(in_place_t, initializer_list<U>, Args&&...);
|
||||
|
||||
// destructor
|
||||
// 5.3.2, Destructor
|
||||
~optional();
|
||||
|
||||
// assignment
|
||||
// 5.3.3, Assignment
|
||||
optional& operator=(nullopt_t) noexcept;
|
||||
optional& operator=(const optional&);
|
||||
optional& operator=(optional&&)
|
||||
noexcept(is_nothrow_move_assignable<T>::value &&
|
||||
is_nothrow_move_constructible<T>::value);
|
||||
optional& operator=(optional&&) noexcept(see below);
|
||||
template <class U> optional& operator=(U&&);
|
||||
template <class... Args> void emplace(Args&&...);
|
||||
template <class U, class... Args> void emplace(initializer_list<U>, Args&&...);
|
||||
template <class U, class... Args>
|
||||
void emplace(initializer_list<U>, Args&&...);
|
||||
|
||||
// swap
|
||||
void swap(optional&)
|
||||
noexcept(is_nothrow_move_constructible<T>::value &&
|
||||
noexcept(swap(declval<T&>(), declval<T&>())));
|
||||
// 5.3.4, Swap
|
||||
void swap(optional&) noexcept(see below);
|
||||
|
||||
// observers
|
||||
// 5.3.5, Observers
|
||||
constexpr T const* operator ->() const;
|
||||
T* operator->();
|
||||
constexpr T const& operator*() const;
|
||||
T& operator*();
|
||||
constexpr T* operator ->();
|
||||
constexpr T const& operator *() const &;
|
||||
constexpr T& operator *() &;
|
||||
constexpr T&& operator *() &&;
|
||||
constexpr const T&& operator *() const &&;
|
||||
constexpr explicit operator bool() const noexcept;
|
||||
constexpr T const& value() const;
|
||||
T& value();
|
||||
constexpr T const& value() const &;
|
||||
constexpr T& value() &;
|
||||
constexpr T&& value() &&;
|
||||
constexpr const T&& value() const &&;
|
||||
template <class U> constexpr T value_or(U&&) const &;
|
||||
template <class U> T value_or(U&&) &&;
|
||||
template <class U> constexpr T value_or(U&&) &&;
|
||||
|
||||
private:
|
||||
T* val; // exposition only
|
||||
};
|
||||
|
||||
// In-place construction
|
||||
struct in_place_t{};
|
||||
constexpr in_place_t in_place{};
|
||||
} // namespace fundamentals_v1
|
||||
} // namespace experimental
|
||||
|
||||
// Disengaged state indicator
|
||||
struct nullopt_t{see below};
|
||||
constexpr nullopt_t nullopt(unspecified);
|
||||
|
||||
// class bad_optional_access
|
||||
class bad_optional_access
|
||||
: public logic_error
|
||||
{
|
||||
public:
|
||||
explicit bad_optional_access(const string& what_arg);
|
||||
explicit bad_optional_access(const char* what_arg);
|
||||
};
|
||||
|
||||
// Relational operators
|
||||
template <class T> constexpr bool operator==(const optional<T>&, const optional<T>&);
|
||||
template <class T> constexpr bool operator< (const optional<T>&, const optional<T>&);
|
||||
|
||||
// Comparison with nullopt
|
||||
template <class T> constexpr bool operator==(const optional<T>&, nullopt_t) noexcept;
|
||||
template <class T> constexpr bool operator==(nullopt_t, const optional<T>&) noexcept;
|
||||
template <class T> constexpr bool operator<(const optional<T>&, nullopt_t) noexcept;
|
||||
template <class T> constexpr bool operator<(nullopt_t, const optional<T>&) noexcept;
|
||||
|
||||
// Comparison with T
|
||||
template <class T> constexpr bool operator==(const optional<T>&, const T&);
|
||||
template <class T> constexpr bool operator==(const T&, const optional<T>&);
|
||||
template <class T> constexpr bool operator<(const optional<T>&, const T&);
|
||||
template <class T> constexpr bool operator<(const T&, const optional<T>&);
|
||||
|
||||
// Specialized algorithms
|
||||
template <class T> void swap(optional<T>&, optional<T>&) noexcept(see below);
|
||||
template <class T> constexpr optional<typename decay<T>::type> make_optional(T&&);
|
||||
|
||||
// hash support
|
||||
// 5.11, Hash support
|
||||
template <class T> struct hash;
|
||||
template <class T> struct hash<optional<T>>;
|
||||
template <class T> struct hash<experimental::optional<T>>;
|
||||
|
||||
}} // std::experimental
|
||||
} // namespace std
|
||||
|
||||
*/
|
||||
|
||||
#include <__config>
|
||||
#include <experimental/__config>
|
||||
#include <functional>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace std { namespace experimental {
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL
|
||||
class _LIBCPP_EXCEPTION_ABI bad_optional_access
|
||||
: public logic_error
|
||||
: public std::logic_error
|
||||
{
|
||||
public:
|
||||
#if _LIBCPP_STD_VER > 11
|
||||
_LIBCPP_INLINE_VISIBILITY explicit bad_optional_access(const string& __arg)
|
||||
: logic_error(__arg) {}
|
||||
_LIBCPP_INLINE_VISIBILITY explicit bad_optional_access(const char* __arg)
|
||||
: logic_error(__arg) {}
|
||||
_LIBCPP_INLINE_VISIBILITY bad_optional_access(const bad_optional_access&) noexcept = default;
|
||||
_LIBCPP_INLINE_VISIBILITY bad_optional_access& operator=(const bad_optional_access&) noexcept = default;
|
||||
#else
|
||||
private:
|
||||
bad_optional_access(const bad_optional_access&);
|
||||
bad_optional_access& operator=(const bad_optional_access&);
|
||||
public:
|
||||
#endif // _LIBCPP_STD_VER > 11
|
||||
// Get the key function ~bad_optional_access() into the dylib even if not compiling for C++1y
|
||||
bad_optional_access() : std::logic_error("Bad optional Access") {}
|
||||
|
||||
// Get the key function ~bad_optional_access() into the dylib
|
||||
virtual ~bad_optional_access() _NOEXCEPT;
|
||||
};
|
||||
|
||||
}} // std::experimental
|
||||
_LIBCPP_END_NAMESPACE_EXPERIMENTAL
|
||||
|
||||
|
||||
#if _LIBCPP_STD_VER > 11
|
||||
|
||||
@@ -148,16 +164,14 @@ public:
|
||||
#include <type_traits>
|
||||
#include <new>
|
||||
#include <__functional_base>
|
||||
|
||||
#include <__undef_min_max>
|
||||
|
||||
#include <__debug>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
#pragma GCC system_header
|
||||
#endif
|
||||
|
||||
namespace std { namespace experimental { inline namespace __library_fundamentals_v1 {
|
||||
_LIBCPP_BEGIN_NAMESPACE_LFTS
|
||||
|
||||
struct in_place_t {};
|
||||
constexpr in_place_t in_place{};
|
||||
@@ -503,7 +517,7 @@ public:
|
||||
constexpr value_type const& value() const
|
||||
{
|
||||
if (!this->__engaged_)
|
||||
throw bad_optional_access("optional<T>::value: not engaged");
|
||||
throw bad_optional_access();
|
||||
return this->__val_;
|
||||
}
|
||||
|
||||
@@ -511,7 +525,7 @@ public:
|
||||
value_type& value()
|
||||
{
|
||||
if (!this->__engaged_)
|
||||
throw bad_optional_access("optional<T>::value: not engaged");
|
||||
throw bad_optional_access();
|
||||
return this->__val_;
|
||||
}
|
||||
|
||||
@@ -556,6 +570,7 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
// Comparisons between optionals
|
||||
template <class _Tp>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
constexpr
|
||||
@@ -569,6 +584,15 @@ operator==(const optional<_Tp>& __x, const optional<_Tp>& __y)
|
||||
return *__x == *__y;
|
||||
}
|
||||
|
||||
template <class _Tp>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
constexpr
|
||||
bool
|
||||
operator!=(const optional<_Tp>& __x, const optional<_Tp>& __y)
|
||||
{
|
||||
return !(__x == __y);
|
||||
}
|
||||
|
||||
template <class _Tp>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
constexpr
|
||||
@@ -579,9 +603,38 @@ operator<(const optional<_Tp>& __x, const optional<_Tp>& __y)
|
||||
return false;
|
||||
if (!static_cast<bool>(__x))
|
||||
return true;
|
||||
return less<_Tp>{}(*__x, *__y);
|
||||
return *__x < *__y;
|
||||
}
|
||||
|
||||
template <class _Tp>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
constexpr
|
||||
bool
|
||||
operator>(const optional<_Tp>& __x, const optional<_Tp>& __y)
|
||||
{
|
||||
return __y < __x;
|
||||
}
|
||||
|
||||
template <class _Tp>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
constexpr
|
||||
bool
|
||||
operator<=(const optional<_Tp>& __x, const optional<_Tp>& __y)
|
||||
{
|
||||
return !(__y < __x);
|
||||
}
|
||||
|
||||
template <class _Tp>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
constexpr
|
||||
bool
|
||||
operator>=(const optional<_Tp>& __x, const optional<_Tp>& __y)
|
||||
{
|
||||
return !(__x < __y);
|
||||
}
|
||||
|
||||
|
||||
// Comparisons with nullopt
|
||||
template <class _Tp>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
constexpr
|
||||
@@ -600,6 +653,24 @@ operator==(nullopt_t, const optional<_Tp>& __x) noexcept
|
||||
return !static_cast<bool>(__x);
|
||||
}
|
||||
|
||||
template <class _Tp>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
constexpr
|
||||
bool
|
||||
operator!=(const optional<_Tp>& __x, nullopt_t) noexcept
|
||||
{
|
||||
return static_cast<bool>(__x);
|
||||
}
|
||||
|
||||
template <class _Tp>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
constexpr
|
||||
bool
|
||||
operator!=(nullopt_t, const optional<_Tp>& __x) noexcept
|
||||
{
|
||||
return static_cast<bool>(__x);
|
||||
}
|
||||
|
||||
template <class _Tp>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
constexpr
|
||||
@@ -618,6 +689,61 @@ operator<(nullopt_t, const optional<_Tp>& __x) noexcept
|
||||
return static_cast<bool>(__x);
|
||||
}
|
||||
|
||||
template <class _Tp>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
constexpr
|
||||
bool
|
||||
operator<=(const optional<_Tp>& __x, nullopt_t) noexcept
|
||||
{
|
||||
return !static_cast<bool>(__x);
|
||||
}
|
||||
|
||||
template <class _Tp>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
constexpr
|
||||
bool
|
||||
operator<=(nullopt_t, const optional<_Tp>& __x) noexcept
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class _Tp>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
constexpr
|
||||
bool
|
||||
operator>(const optional<_Tp>& __x, nullopt_t) noexcept
|
||||
{
|
||||
return static_cast<bool>(__x);
|
||||
}
|
||||
|
||||
template <class _Tp>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
constexpr
|
||||
bool
|
||||
operator>(nullopt_t, const optional<_Tp>& __x) noexcept
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
template <class _Tp>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
constexpr
|
||||
bool
|
||||
operator>=(const optional<_Tp>&, nullopt_t) noexcept
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class _Tp>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
constexpr
|
||||
bool
|
||||
operator>=(nullopt_t, const optional<_Tp>& __x) noexcept
|
||||
{
|
||||
return !static_cast<bool>(__x);
|
||||
}
|
||||
|
||||
// Comparisons with T
|
||||
template <class _Tp>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
constexpr
|
||||
@@ -636,6 +762,24 @@ operator==(const _Tp& __v, const optional<_Tp>& __x)
|
||||
return static_cast<bool>(__x) ? *__x == __v : false;
|
||||
}
|
||||
|
||||
template <class _Tp>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
constexpr
|
||||
bool
|
||||
operator!=(const optional<_Tp>& __x, const _Tp& __v)
|
||||
{
|
||||
return static_cast<bool>(__x) ? !(*__x == __v) : true;
|
||||
}
|
||||
|
||||
template <class _Tp>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
constexpr
|
||||
bool
|
||||
operator!=(const _Tp& __v, const optional<_Tp>& __x)
|
||||
{
|
||||
return static_cast<bool>(__x) ? !(*__x == __v) : true;
|
||||
}
|
||||
|
||||
template <class _Tp>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
constexpr
|
||||
@@ -654,6 +798,61 @@ operator<(const _Tp& __v, const optional<_Tp>& __x)
|
||||
return static_cast<bool>(__x) ? less<_Tp>{}(__v, *__x) : false;
|
||||
}
|
||||
|
||||
template <class _Tp>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
constexpr
|
||||
bool
|
||||
operator<=(const optional<_Tp>& __x, const _Tp& __v)
|
||||
{
|
||||
return !(__x > __v);
|
||||
}
|
||||
|
||||
template <class _Tp>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
constexpr
|
||||
bool
|
||||
operator<=(const _Tp& __v, const optional<_Tp>& __x)
|
||||
{
|
||||
return !(__v > __x);
|
||||
}
|
||||
|
||||
template <class _Tp>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
constexpr
|
||||
bool
|
||||
operator>(const optional<_Tp>& __x, const _Tp& __v)
|
||||
{
|
||||
return static_cast<bool>(__x) ? __v < __x : false;
|
||||
}
|
||||
|
||||
template <class _Tp>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
constexpr
|
||||
bool
|
||||
operator>(const _Tp& __v, const optional<_Tp>& __x)
|
||||
{
|
||||
return static_cast<bool>(__x) ? __x < __v : true;
|
||||
}
|
||||
|
||||
template <class _Tp>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
constexpr
|
||||
bool
|
||||
operator>=(const optional<_Tp>& __x, const _Tp& __v)
|
||||
{
|
||||
return !(__x < __v);
|
||||
}
|
||||
|
||||
template <class _Tp>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
constexpr
|
||||
bool
|
||||
operator>=(const _Tp& __v, const optional<_Tp>& __x)
|
||||
{
|
||||
return !(__v < __x);
|
||||
}
|
||||
|
||||
|
||||
template <class _Tp>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
void
|
||||
@@ -671,7 +870,7 @@ make_optional(_Tp&& __v)
|
||||
return optional<typename decay<_Tp>::type>(_VSTD::forward<_Tp>(__v));
|
||||
}
|
||||
|
||||
}}} // namespace std::experimental::__library_fundamentals_v1
|
||||
_LIBCPP_END_NAMESPACE_LFTS
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
|
||||
423
include/experimental/type_traits
Normal file
423
include/experimental/type_traits
Normal file
@@ -0,0 +1,423 @@
|
||||
// -*- C++ -*-
|
||||
//===-------------------------- type_traits -------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP_EXPERIMENTAL_TYPE_TRAITS
|
||||
#define _LIBCPP_EXPERIMENTAL_TYPE_TRAITS
|
||||
|
||||
/**
|
||||
experimental/type_traits synopsis
|
||||
|
||||
// C++1y
|
||||
#include <type_traits>
|
||||
|
||||
namespace std {
|
||||
namespace experimental {
|
||||
inline namespace fundamentals_v1 {
|
||||
|
||||
// See C++14 20.10.4.1, primary type categories
|
||||
template <class T> constexpr bool is_void_v
|
||||
= is_void<T>::value;
|
||||
template <class T> constexpr bool is_null_pointer_v
|
||||
= is_null_pointer<T>::value;
|
||||
template <class T> constexpr bool is_integral_v
|
||||
= is_integral<T>::value;
|
||||
template <class T> constexpr bool is_floating_point_v
|
||||
= is_floating_point<T>::value;
|
||||
template <class T> constexpr bool is_array_v
|
||||
= is_array<T>::value;
|
||||
template <class T> constexpr bool is_pointer_v
|
||||
= is_pointer<T>::value;
|
||||
template <class T> constexpr bool is_lvalue_reference_v
|
||||
= is_lvalue_reference<T>::value;
|
||||
template <class T> constexpr bool is_rvalue_reference_v
|
||||
= is_rvalue_reference<T>::value;
|
||||
template <class T> constexpr bool is_member_object_pointer_v
|
||||
= is_member_object_pointer<T>::value;
|
||||
template <class T> constexpr bool is_member_function_pointer_v
|
||||
= is_member_function_pointer<T>::value;
|
||||
template <class T> constexpr bool is_enum_v
|
||||
= is_enum<T>::value;
|
||||
template <class T> constexpr bool is_union_v
|
||||
= is_union<T>::value;
|
||||
template <class T> constexpr bool is_class_v
|
||||
= is_class<T>::value;
|
||||
template <class T> constexpr bool is_function_v
|
||||
= is_function<T>::value;
|
||||
|
||||
// See C++14 20.10.4.2, composite type categories
|
||||
template <class T> constexpr bool is_reference_v
|
||||
= is_reference<T>::value;
|
||||
template <class T> constexpr bool is_arithmetic_v
|
||||
= is_arithmetic<T>::value;
|
||||
template <class T> constexpr bool is_fundamental_v
|
||||
= is_fundamental<T>::value;
|
||||
template <class T> constexpr bool is_object_v
|
||||
= is_object<T>::value;
|
||||
template <class T> constexpr bool is_scalar_v
|
||||
= is_scalar<T>::value;
|
||||
template <class T> constexpr bool is_compound_v
|
||||
= is_compound<T>::value;
|
||||
template <class T> constexpr bool is_member_pointer_v
|
||||
= is_member_pointer<T>::value;
|
||||
|
||||
// See C++14 20.10.4.3, type properties
|
||||
template <class T> constexpr bool is_const_v
|
||||
= is_const<T>::value;
|
||||
template <class T> constexpr bool is_volatile_v
|
||||
= is_volatile<T>::value;
|
||||
template <class T> constexpr bool is_trivial_v
|
||||
= is_trivial<T>::value;
|
||||
template <class T> constexpr bool is_trivially_copyable_v
|
||||
= is_trivially_copyable<T>::value;
|
||||
template <class T> constexpr bool is_standard_layout_v
|
||||
= is_standard_layout<T>::value;
|
||||
template <class T> constexpr bool is_pod_v
|
||||
= is_pod<T>::value;
|
||||
template <class T> constexpr bool is_literal_type_v
|
||||
= is_literal_type<T>::value;
|
||||
template <class T> constexpr bool is_empty_v
|
||||
= is_empty<T>::value;
|
||||
template <class T> constexpr bool is_polymorphic_v
|
||||
= is_polymorphic<T>::value;
|
||||
template <class T> constexpr bool is_abstract_v
|
||||
= is_abstract<T>::value;
|
||||
template <class T> constexpr bool is_final_v
|
||||
= is_final<T>::value;
|
||||
template <class T> constexpr bool is_signed_v
|
||||
= is_signed<T>::value;
|
||||
template <class T> constexpr bool is_unsigned_v
|
||||
= is_unsigned<T>::value;
|
||||
template <class T, class... Args> constexpr bool is_constructible_v
|
||||
= is_constructible<T, Args...>::value;
|
||||
template <class T> constexpr bool is_default_constructible_v
|
||||
= is_default_constructible<T>::value;
|
||||
template <class T> constexpr bool is_copy_constructible_v
|
||||
= is_copy_constructible<T>::value;
|
||||
template <class T> constexpr bool is_move_constructible_v
|
||||
= is_move_constructible<T>::value;
|
||||
template <class T, class U> constexpr bool is_assignable_v
|
||||
= is_assignable<T, U>::value;
|
||||
template <class T> constexpr bool is_copy_assignable_v
|
||||
= is_copy_assignable<T>::value;
|
||||
template <class T> constexpr bool is_move_assignable_v
|
||||
= is_move_assignable<T>::value;
|
||||
template <class T> constexpr bool is_destructible_v
|
||||
= is_destructible<T>::value;
|
||||
template <class T, class... Args> constexpr bool is_trivially_constructible_v
|
||||
= is_trivially_constructible<T, Args...>::value;
|
||||
template <class T> constexpr bool is_trivially_default_constructible_v
|
||||
= is_trivially_default_constructible<T>::value;
|
||||
template <class T> constexpr bool is_trivially_copy_constructible_v
|
||||
= is_trivially_copy_constructible<T>::value;
|
||||
template <class T> constexpr bool is_trivially_move_constructible_v
|
||||
= is_trivially_move_constructible<T>::value;
|
||||
template <class T, class U> constexpr bool is_trivially_assignable_v
|
||||
= is_trivially_assignable<T, U>::value;
|
||||
template <class T> constexpr bool is_trivially_copy_assignable_v
|
||||
= is_trivially_copy_assignable<T>::value;
|
||||
template <class T> constexpr bool is_trivially_move_assignable_v
|
||||
= is_trivially_move_assignable<T>::value;
|
||||
template <class T> constexpr bool is_trivially_destructible_v
|
||||
= is_trivially_destructible<T>::value;
|
||||
template <class T, class... Args> constexpr bool is_nothrow_constructible_v
|
||||
= is_nothrow_constructible<T, Args...>::value;
|
||||
template <class T> constexpr bool is_nothrow_default_constructible_v
|
||||
= is_nothrow_default_constructible<T>::value;
|
||||
template <class T> constexpr bool is_nothrow_copy_constructible_v
|
||||
= is_nothrow_copy_constructible<T>::value;
|
||||
template <class T> constexpr bool is_nothrow_move_constructible_v
|
||||
= is_nothrow_move_constructible<T>::value;
|
||||
template <class T, class U> constexpr bool is_nothrow_assignable_v
|
||||
= is_nothrow_assignable<T, U>::value;
|
||||
template <class T> constexpr bool is_nothrow_copy_assignable_v
|
||||
= is_nothrow_copy_assignable<T>::value;
|
||||
template <class T> constexpr bool is_nothrow_move_assignable_v
|
||||
= is_nothrow_move_assignable<T>::value;
|
||||
template <class T> constexpr bool is_nothrow_destructible_v
|
||||
= is_nothrow_destructible<T>::value;
|
||||
template <class T> constexpr bool has_virtual_destructor_v
|
||||
= has_virtual_destructor<T>::value;
|
||||
|
||||
// See C++14 20.10.5, type property queries
|
||||
template <class T> constexpr size_t alignment_of_v
|
||||
= alignment_of<T>::value;
|
||||
template <class T> constexpr size_t rank_v
|
||||
= rank<T>::value;
|
||||
template <class T, unsigned I = 0> constexpr size_t extent_v
|
||||
= extent<T, I>::value;
|
||||
|
||||
// See C++14 20.10.6, type relations
|
||||
template <class T, class U> constexpr bool is_same_v
|
||||
= is_same<T, U>::value;
|
||||
template <class Base, class Derived> constexpr bool is_base_of_v
|
||||
= is_base_of<Base, Derived>::value;
|
||||
template <class From, class To> constexpr bool is_convertible_v
|
||||
= is_convertible<From, To>::value;
|
||||
|
||||
// 3.3.2, Other type transformations
|
||||
template <class> class invocation_type; // not defined
|
||||
template <class F, class... ArgTypes> class invocation_type<F(ArgTypes...)>;
|
||||
template <class> class raw_invocation_type; // not defined
|
||||
template <class F, class... ArgTypes> class raw_invocation_type<F(ArgTypes...)>;
|
||||
|
||||
template <class T>
|
||||
using invocation_type_t = typename invocation_type<T>::type;
|
||||
template <class T>
|
||||
using raw_invocation_type_t = typename raw_invocation_type<T>::type;
|
||||
|
||||
} // namespace fundamentals_v1
|
||||
} // namespace experimental
|
||||
} // namespace std
|
||||
|
||||
*/
|
||||
|
||||
#include <experimental/__config>
|
||||
|
||||
#if _LIBCPP_STD_VER > 11
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_LFTS
|
||||
|
||||
#if __has_feature(cxx_variable_templates)
|
||||
|
||||
// C++14 20.10.4.1, primary type categories
|
||||
|
||||
template <class _Tp> _LIBCPP_CONSTEXPR bool is_void_v
|
||||
= is_void<_Tp>::value;
|
||||
|
||||
template <class _Tp> _LIBCPP_CONSTEXPR bool is_null_pointer_v
|
||||
= is_null_pointer<_Tp>::value;
|
||||
|
||||
template <class _Tp> _LIBCPP_CONSTEXPR bool is_integral_v
|
||||
= is_integral<_Tp>::value;
|
||||
|
||||
template <class _Tp> _LIBCPP_CONSTEXPR bool is_floating_point_v
|
||||
= is_floating_point<_Tp>::value;
|
||||
|
||||
template <class _Tp> _LIBCPP_CONSTEXPR bool is_array_v
|
||||
= is_array<_Tp>::value;
|
||||
|
||||
template <class _Tp> _LIBCPP_CONSTEXPR bool is_pointer_v
|
||||
= is_pointer<_Tp>::value;
|
||||
|
||||
template <class _Tp> _LIBCPP_CONSTEXPR bool is_lvalue_reference_v
|
||||
= is_lvalue_reference<_Tp>::value;
|
||||
|
||||
template <class _Tp> _LIBCPP_CONSTEXPR bool is_rvalue_reference_v
|
||||
= is_rvalue_reference<_Tp>::value;
|
||||
|
||||
template <class _Tp> _LIBCPP_CONSTEXPR bool is_member_object_pointer_v
|
||||
= is_member_object_pointer<_Tp>::value;
|
||||
|
||||
template <class _Tp> _LIBCPP_CONSTEXPR bool is_member_function_pointer_v
|
||||
= is_member_function_pointer<_Tp>::value;
|
||||
|
||||
template <class _Tp> _LIBCPP_CONSTEXPR bool is_enum_v
|
||||
= is_enum<_Tp>::value;
|
||||
|
||||
template <class _Tp> _LIBCPP_CONSTEXPR bool is_union_v
|
||||
= is_union<_Tp>::value;
|
||||
|
||||
template <class _Tp> _LIBCPP_CONSTEXPR bool is_class_v
|
||||
= is_class<_Tp>::value;
|
||||
|
||||
template <class _Tp> _LIBCPP_CONSTEXPR bool is_function_v
|
||||
= is_function<_Tp>::value;
|
||||
|
||||
// C++14 20.10.4.2, composite type categories
|
||||
|
||||
template <class _Tp> _LIBCPP_CONSTEXPR bool is_reference_v
|
||||
= is_reference<_Tp>::value;
|
||||
|
||||
template <class _Tp> _LIBCPP_CONSTEXPR bool is_arithmetic_v
|
||||
= is_arithmetic<_Tp>::value;
|
||||
|
||||
template <class _Tp> _LIBCPP_CONSTEXPR bool is_fundamental_v
|
||||
= is_fundamental<_Tp>::value;
|
||||
|
||||
template <class _Tp> _LIBCPP_CONSTEXPR bool is_object_v
|
||||
= is_object<_Tp>::value;
|
||||
|
||||
template <class _Tp> _LIBCPP_CONSTEXPR bool is_scalar_v
|
||||
= is_scalar<_Tp>::value;
|
||||
|
||||
template <class _Tp> _LIBCPP_CONSTEXPR bool is_compound_v
|
||||
= is_compound<_Tp>::value;
|
||||
|
||||
template <class _Tp> _LIBCPP_CONSTEXPR bool is_member_pointer_v
|
||||
= is_member_pointer<_Tp>::value;
|
||||
|
||||
// C++14 20.10.4.3, type properties
|
||||
|
||||
template <class _Tp> _LIBCPP_CONSTEXPR bool is_const_v
|
||||
= is_const<_Tp>::value;
|
||||
|
||||
template <class _Tp> _LIBCPP_CONSTEXPR bool is_volatile_v
|
||||
= is_volatile<_Tp>::value;
|
||||
|
||||
template <class _Tp> _LIBCPP_CONSTEXPR bool is_trivial_v
|
||||
= is_trivial<_Tp>::value;
|
||||
|
||||
template <class _Tp> _LIBCPP_CONSTEXPR bool is_trivially_copyable_v
|
||||
= is_trivially_copyable<_Tp>::value;
|
||||
|
||||
template <class _Tp> _LIBCPP_CONSTEXPR bool is_standard_layout_v
|
||||
= is_standard_layout<_Tp>::value;
|
||||
|
||||
template <class _Tp> _LIBCPP_CONSTEXPR bool is_pod_v
|
||||
= is_pod<_Tp>::value;
|
||||
|
||||
template <class _Tp> _LIBCPP_CONSTEXPR bool is_literal_type_v
|
||||
= is_literal_type<_Tp>::value;
|
||||
|
||||
template <class _Tp> _LIBCPP_CONSTEXPR bool is_empty_v
|
||||
= is_empty<_Tp>::value;
|
||||
|
||||
template <class _Tp> _LIBCPP_CONSTEXPR bool is_polymorphic_v
|
||||
= is_polymorphic<_Tp>::value;
|
||||
|
||||
template <class _Tp> _LIBCPP_CONSTEXPR bool is_abstract_v
|
||||
= is_abstract<_Tp>::value;
|
||||
|
||||
template <class _Tp> _LIBCPP_CONSTEXPR bool is_final_v
|
||||
= is_final<_Tp>::value;
|
||||
|
||||
template <class _Tp> _LIBCPP_CONSTEXPR bool is_signed_v
|
||||
= is_signed<_Tp>::value;
|
||||
|
||||
template <class _Tp> _LIBCPP_CONSTEXPR bool is_unsigned_v
|
||||
= is_unsigned<_Tp>::value;
|
||||
|
||||
template <class _Tp, class ..._Ts> _LIBCPP_CONSTEXPR bool is_constructible_v
|
||||
= is_constructible<_Tp, _Ts...>::value;
|
||||
|
||||
template <class _Tp> _LIBCPP_CONSTEXPR bool is_default_constructible_v
|
||||
= is_default_constructible<_Tp>::value;
|
||||
|
||||
template <class _Tp> _LIBCPP_CONSTEXPR bool is_copy_constructible_v
|
||||
= is_copy_constructible<_Tp>::value;
|
||||
|
||||
template <class _Tp> _LIBCPP_CONSTEXPR bool is_move_constructible_v
|
||||
= is_move_constructible<_Tp>::value;
|
||||
|
||||
template <class _Tp, class _Up> _LIBCPP_CONSTEXPR bool is_assignable_v
|
||||
= is_assignable<_Tp, _Up>::value;
|
||||
|
||||
template <class _Tp> _LIBCPP_CONSTEXPR bool is_copy_assignable_v
|
||||
= is_copy_assignable<_Tp>::value;
|
||||
|
||||
template <class _Tp> _LIBCPP_CONSTEXPR bool is_move_assignable_v
|
||||
= is_move_assignable<_Tp>::value;
|
||||
|
||||
template <class _Tp> _LIBCPP_CONSTEXPR bool is_destructible_v
|
||||
= is_destructible<_Tp>::value;
|
||||
|
||||
template <class _Tp, class ..._Ts> _LIBCPP_CONSTEXPR bool is_trivially_constructible_v
|
||||
= is_trivially_constructible<_Tp, _Ts...>::value;
|
||||
|
||||
template <class _Tp> _LIBCPP_CONSTEXPR bool is_trivially_default_constructible_v
|
||||
= is_trivially_default_constructible<_Tp>::value;
|
||||
|
||||
template <class _Tp> _LIBCPP_CONSTEXPR bool is_trivially_copy_constructible_v
|
||||
= is_trivially_copy_constructible<_Tp>::value;
|
||||
|
||||
template <class _Tp> _LIBCPP_CONSTEXPR bool is_trivially_move_constructible_v
|
||||
= is_trivially_move_constructible<_Tp>::value;
|
||||
|
||||
template <class _Tp, class _Up> _LIBCPP_CONSTEXPR bool is_trivially_assignable_v
|
||||
= is_trivially_assignable<_Tp, _Up>::value;
|
||||
|
||||
template <class _Tp> _LIBCPP_CONSTEXPR bool is_trivially_copy_assignable_v
|
||||
= is_trivially_copy_assignable<_Tp>::value;
|
||||
|
||||
template <class _Tp> _LIBCPP_CONSTEXPR bool is_trivially_move_assignable_v
|
||||
= is_trivially_move_assignable<_Tp>::value;
|
||||
|
||||
template <class _Tp> _LIBCPP_CONSTEXPR bool is_trivially_destructible_v
|
||||
= is_trivially_destructible<_Tp>::value;
|
||||
|
||||
template <class _Tp, class ..._Ts> _LIBCPP_CONSTEXPR bool is_nothrow_constructible_v
|
||||
= is_nothrow_constructible<_Tp, _Ts...>::value;
|
||||
|
||||
template <class _Tp> _LIBCPP_CONSTEXPR bool is_nothrow_default_constructible_v
|
||||
= is_nothrow_default_constructible<_Tp>::value;
|
||||
|
||||
template <class _Tp> _LIBCPP_CONSTEXPR bool is_nothrow_copy_constructible_v
|
||||
= is_nothrow_copy_constructible<_Tp>::value;
|
||||
|
||||
template <class _Tp> _LIBCPP_CONSTEXPR bool is_nothrow_move_constructible_v
|
||||
= is_nothrow_move_constructible<_Tp>::value;
|
||||
|
||||
template <class _Tp, class _Up> _LIBCPP_CONSTEXPR bool is_nothrow_assignable_v
|
||||
= is_nothrow_assignable<_Tp, _Up>::value;
|
||||
|
||||
template <class _Tp> _LIBCPP_CONSTEXPR bool is_nothrow_copy_assignable_v
|
||||
= is_nothrow_copy_assignable<_Tp>::value;
|
||||
|
||||
template <class _Tp> _LIBCPP_CONSTEXPR bool is_nothrow_move_assignable_v
|
||||
= is_nothrow_move_assignable<_Tp>::value;
|
||||
|
||||
template <class _Tp> _LIBCPP_CONSTEXPR bool is_nothrow_destructible_v
|
||||
= is_nothrow_destructible<_Tp>::value;
|
||||
|
||||
template <class _Tp> _LIBCPP_CONSTEXPR bool has_virtual_destructor_v
|
||||
= has_virtual_destructor<_Tp>::value;
|
||||
|
||||
// C++14 20.10.5, type properties queries
|
||||
|
||||
template <class _Tp> _LIBCPP_CONSTEXPR size_t alignment_of_v
|
||||
= alignment_of<_Tp>::value;
|
||||
|
||||
template <class _Tp> _LIBCPP_CONSTEXPR size_t rank_v
|
||||
= rank<_Tp>::value;
|
||||
|
||||
template <class _Tp, unsigned _Id = 0> _LIBCPP_CONSTEXPR size_t extent_v
|
||||
= extent<_Tp, _Id>::value;
|
||||
|
||||
// C++14 20.10.6, type relations
|
||||
|
||||
template <class _Tp, class _Up> _LIBCPP_CONSTEXPR bool is_same_v
|
||||
= is_same<_Tp, _Up>::value;
|
||||
|
||||
template <class _Tp, class _Up> _LIBCPP_CONSTEXPR bool is_base_of_v
|
||||
= is_base_of<_Tp, _Up>::value;
|
||||
|
||||
template <class _Tp, class _Up> _LIBCPP_CONSTEXPR bool is_convertible_v
|
||||
= is_convertible<_Tp, _Up>::value;
|
||||
|
||||
#endif /* __has_feature(cxx_variable_templates) */
|
||||
|
||||
// 3.3.2, Other type transformations
|
||||
/*
|
||||
template <class>
|
||||
class _LIBCPP_TYPE_VIS_ONLY raw_invocation_type;
|
||||
|
||||
template <class _Fn, class ..._Args>
|
||||
class _LIBCPP_TYPE_VIS_ONLY raw_invocation_type<_Fn(_Args...)>;
|
||||
|
||||
template <class>
|
||||
class _LIBCPP_TYPE_VIS_ONLY invokation_type;
|
||||
|
||||
template <class _Fn, class ..._Args>
|
||||
class _LIBCPP_TYPE_VIS_ONLY invokation_type<_Fn(_Args...)>;
|
||||
|
||||
template <class _Tp>
|
||||
using invokation_type_t = typename invokation_type<_Tp>::type;
|
||||
|
||||
template <class _Tp>
|
||||
using raw_invocation_type_t = typename raw_invocation_type<_Tp>::type;
|
||||
*/
|
||||
|
||||
_LIBCPP_END_NAMESPACE_LFTS
|
||||
|
||||
#endif /* _LIBCPP_STD_VER > 11 */
|
||||
|
||||
#endif /* _LIBCPP_EXPERIMENTAL_TYPE_TRAITS */
|
||||
@@ -1863,10 +1863,10 @@ __mu_expand(_Ti& __ti, tuple<_Uj...>& __uj, __tuple_indices<_Indx...>)
|
||||
|
||||
template <class _Ti, class ..._Uj>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
typename enable_if
|
||||
typename __lazy_enable_if
|
||||
<
|
||||
is_bind_expression<_Ti>::value,
|
||||
typename __invoke_of<_Ti&, _Uj...>::type
|
||||
__invoke_of<_Ti&, _Uj...>
|
||||
>::type
|
||||
__mu(_Ti& __ti, tuple<_Uj...>& __uj)
|
||||
{
|
||||
|
||||
@@ -237,7 +237,7 @@ protected:
|
||||
static _LIBCPP_CONSTEXPR const bool is_bounded = true;
|
||||
static _LIBCPP_CONSTEXPR const bool is_modulo = !_VSTD::is_signed<_Tp>::value;
|
||||
|
||||
#if __i386__ || __x86_64__
|
||||
#if defined(__i386__) || defined(__x86_64__) || defined(__pnacl__)
|
||||
static _LIBCPP_CONSTEXPR const bool traps = true;
|
||||
#else
|
||||
static _LIBCPP_CONSTEXPR const bool traps = false;
|
||||
|
||||
@@ -178,6 +178,7 @@ template<class Callable, class ...Args>
|
||||
#ifndef _LIBCPP_HAS_NO_VARIADICS
|
||||
#include <tuple>
|
||||
#endif
|
||||
#include <sched.h>
|
||||
|
||||
#include <__undef_min_max>
|
||||
|
||||
|
||||
@@ -3475,9 +3475,9 @@ typedef shuffle_order_engine<minstd_rand0, 256> knuth_b;
|
||||
|
||||
class _LIBCPP_TYPE_VIS random_device
|
||||
{
|
||||
#if !defined(_WIN32)
|
||||
#if !(defined(_WIN32) || defined(_LIBCPP_USING_NACL_RANDOM))
|
||||
int __f_;
|
||||
#endif // defined(_WIN32)
|
||||
#endif // !(defined(_WIN32) || defined(_LIBCPP_USING_NACL_RANDOM))
|
||||
public:
|
||||
// types
|
||||
typedef unsigned result_type;
|
||||
|
||||
@@ -4935,7 +4935,7 @@ bool
|
||||
operator==(const basic_string<typename iterator_traits<_BiIter>::value_type, _ST, _SA>& __x,
|
||||
const sub_match<_BiIter>& __y)
|
||||
{
|
||||
return __y.compare(__x.c_str()) == 0;
|
||||
return __y.compare(typename sub_match<_BiIter>::string_type(__x.data(), __x.size())) == 0;
|
||||
}
|
||||
|
||||
template <class _BiIter, class _ST, class _SA>
|
||||
@@ -4953,7 +4953,7 @@ bool
|
||||
operator<(const basic_string<typename iterator_traits<_BiIter>::value_type, _ST, _SA>& __x,
|
||||
const sub_match<_BiIter>& __y)
|
||||
{
|
||||
return __y.compare(__x.c_str()) > 0;
|
||||
return __y.compare(typename sub_match<_BiIter>::string_type(__x.data(), __x.size())) > 0;
|
||||
}
|
||||
|
||||
template <class _BiIter, class _ST, class _SA>
|
||||
@@ -4988,7 +4988,7 @@ bool
|
||||
operator==(const sub_match<_BiIter>& __x,
|
||||
const basic_string<typename iterator_traits<_BiIter>::value_type, _ST, _SA>& __y)
|
||||
{
|
||||
return __x.compare(__y.c_str()) == 0;
|
||||
return __x.compare(typename sub_match<_BiIter>::string_type(__y.data(), __y.size())) == 0;
|
||||
}
|
||||
|
||||
template <class _BiIter, class _ST, class _SA>
|
||||
@@ -5006,7 +5006,7 @@ bool
|
||||
operator<(const sub_match<_BiIter>& __x,
|
||||
const basic_string<typename iterator_traits<_BiIter>::value_type, _ST, _SA>& __y)
|
||||
{
|
||||
return __x.compare(__y.c_str()) < 0;
|
||||
return __x.compare(typename sub_match<_BiIter>::string_type(__y.data(), __y.size())) < 0;
|
||||
}
|
||||
|
||||
template <class _BiIter, class _ST, class _SA>
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
#ifndef __XLOCALE_H_INCLUDED
|
||||
#define __XLOCALE_H_INCLUDED
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
@@ -99,6 +99,7 @@ void sleep_for(const chrono::duration<Rep, Period>& rel_time);
|
||||
#include <tuple>
|
||||
#endif
|
||||
#include <pthread.h>
|
||||
#include <sched.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
#pragma GCC system_header
|
||||
|
||||
@@ -376,9 +376,9 @@ template <class ..._Tp>
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
void __swallow(_Tp&&...) _NOEXCEPT {}
|
||||
|
||||
template <bool ..._B>
|
||||
template <bool ..._Pred>
|
||||
struct __all
|
||||
: is_same<__all<_B...>, __all<(_B, true)...>>
|
||||
: is_same<__all<_Pred...>, __all<(_Pred, true)...>>
|
||||
{ };
|
||||
|
||||
template <class _Tp>
|
||||
|
||||
@@ -202,6 +202,10 @@ operator>=(const _Tp& __x, const _Tp& __y)
|
||||
|
||||
// swap_ranges
|
||||
|
||||
// forward
|
||||
template<class _Tp, size_t _Np>
|
||||
void swap(_Tp (&__a)[_Np], _Tp (&__b)[_Np]) _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value);
|
||||
|
||||
template <class _ForwardIterator1, class _ForwardIterator2>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
_ForwardIterator2
|
||||
|
||||
@@ -3,6 +3,9 @@ file(GLOB LIBCXX_SOURCES ../src/*.cpp)
|
||||
if(WIN32)
|
||||
file(GLOB LIBCXX_WIN32_SOURCES ../src/support/win32/*.cpp)
|
||||
list(APPEND LIBCXX_SOURCES ${LIBCXX_WIN32_SOURCES})
|
||||
elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "SunOS")
|
||||
file(GLOB LIBCXX_SOLARIS_SOURCES ../src/support/solaris/*.c)
|
||||
list(APPEND LIBCXX_SOURCES ${LIBCXX_SOLARIS_SOURCES})
|
||||
endif()
|
||||
|
||||
# Add all the headers to the project for IDEs.
|
||||
@@ -101,6 +104,6 @@ set_target_properties(cxx
|
||||
)
|
||||
|
||||
install(TARGETS cxx
|
||||
LIBRARY DESTINATION lib${LLVM_LIBDIR_SUFFIX}
|
||||
ARCHIVE DESTINATION lib${LLVM_LIBDIR_SUFFIX}
|
||||
LIBRARY DESTINATION lib${LIBCXX_LIBDIR_SUFFIX}
|
||||
ARCHIVE DESTINATION lib${LIBCXX_LIBDIR_SUFFIX}
|
||||
)
|
||||
|
||||
@@ -111,7 +111,7 @@ __shared_weak_count::lock() _NOEXCEPT
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef _LIBCPP_NO_RTTI
|
||||
#if !defined(_LIBCPP_NO_RTTI) || !defined(_LIBCPP_BUILD_STATIC)
|
||||
|
||||
const void*
|
||||
__shared_weak_count::__get_deleter(const type_info&) const _NOEXCEPT
|
||||
|
||||
@@ -9,8 +9,7 @@
|
||||
|
||||
#include "experimental/optional"
|
||||
|
||||
namespace std // purposefully not using versioning namespace
|
||||
{ namespace experimental {
|
||||
_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL
|
||||
|
||||
#ifdef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
|
||||
|
||||
@@ -22,4 +21,4 @@ bad_optional_access::~bad_optional_access() _NOEXCEPT = default;
|
||||
|
||||
#endif
|
||||
|
||||
}} // std::experimental
|
||||
_LIBCPP_END_NAMESPACE_EXPERIMENTAL
|
||||
|
||||
@@ -11,23 +11,27 @@
|
||||
// Must be defined before including stdlib.h to enable rand_s().
|
||||
#define _CRT_RAND_S
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
#endif // defined(_WIN32)
|
||||
|
||||
#include "random"
|
||||
#include "system_error"
|
||||
|
||||
#ifdef __sun__
|
||||
#if defined(__sun__)
|
||||
#define rename solaris_headers_are_broken
|
||||
#endif
|
||||
#endif // defined(__sun__)
|
||||
#if !defined(_WIN32)
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#endif // defined(_WIN32)
|
||||
#endif // !defined(_WIN32)
|
||||
#include <errno.h>
|
||||
#if defined(_LIBCPP_USING_NACL_RANDOM)
|
||||
#include <nacl/nacl_random.h>
|
||||
#endif // defined(_LIBCPP_USING_NACL_RANDOM)
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#if defined(_WIN32)
|
||||
|
||||
random_device::random_device(const string&)
|
||||
{
|
||||
}
|
||||
@@ -45,7 +49,39 @@ random_device::operator()()
|
||||
__throw_system_error(err, "random_device rand_s failed.");
|
||||
return r;
|
||||
}
|
||||
#else
|
||||
|
||||
#elif defined(_LIBCPP_USING_NACL_RANDOM)
|
||||
|
||||
random_device::random_device(const string& __token)
|
||||
{
|
||||
if (__token != "/dev/urandom")
|
||||
__throw_system_error(ENOENT, ("random device not supported " + __token).c_str());
|
||||
int error = nacl_secure_random_init();
|
||||
if (error)
|
||||
__throw_system_error(error, ("random device failed to open " + __token).c_str());
|
||||
}
|
||||
|
||||
random_device::~random_device()
|
||||
{
|
||||
}
|
||||
|
||||
unsigned
|
||||
random_device::operator()()
|
||||
{
|
||||
unsigned r;
|
||||
size_t n = sizeof(r);
|
||||
char* p = reinterpret_cast<char*>(&r);
|
||||
size_t bytes_written;
|
||||
int error = nacl_secure_random(&r, n, &bytes_written);
|
||||
if (error != 0)
|
||||
__throw_system_error(error, "random_device failed getting bytes");
|
||||
else if (bytes_written != n)
|
||||
__throw_runtime_error("random_device failed to obtain enough bytes");
|
||||
return r;
|
||||
}
|
||||
|
||||
#else // !defined(_WIN32) && !defined(_LIBCPP_USING_NACL_RANDOM)
|
||||
|
||||
random_device::random_device(const string& __token)
|
||||
: __f_(open(__token.c_str(), O_RDONLY))
|
||||
{
|
||||
@@ -80,7 +116,8 @@ random_device::operator()()
|
||||
}
|
||||
return r;
|
||||
}
|
||||
#endif // defined(_WIN32)
|
||||
|
||||
#endif // defined(_WIN32) || defined(_LIBCPP_USING_NACL_RANDOM)
|
||||
|
||||
double
|
||||
random_device::entropy() const _NOEXCEPT
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
#include <limits.h>
|
||||
#include <assert.h>
|
||||
#include <sys/localedef.h>
|
||||
#include "xlocale.h"
|
||||
#include "support/solaris/xlocale.h"
|
||||
|
||||
static _LC_locale_t *__C_locale;
|
||||
|
||||
|
||||
@@ -17,9 +17,9 @@
|
||||
#include "limits"
|
||||
#include <sys/types.h>
|
||||
#if !defined(_WIN32)
|
||||
#if !defined(__sun__) && !defined(__linux__) && !defined(_AIX)
|
||||
# if !defined(__sun__) && !defined(__linux__) && !defined(_AIX) && !defined(__native_client__)
|
||||
# include <sys/sysctl.h>
|
||||
#endif // !__sun__ && !__linux__ && !_AIX
|
||||
# endif // !defined(__sun__) && !defined(__linux__) && !defined(_AIX) && !defined(__native_client__)
|
||||
# include <unistd.h>
|
||||
#endif // !_WIN32
|
||||
|
||||
|
||||
@@ -23,11 +23,12 @@ if(PYTHONINTERP_FOUND)
|
||||
set(LIT_ARGS "${LLVM_LIT_ARGS}")
|
||||
separate_arguments(LIT_ARGS)
|
||||
|
||||
set(LIBCXX_COMPILER ${CMAKE_CXX_COMPILER})
|
||||
set(LIBCXX_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/..)
|
||||
set(LIBCXX_BINARY_DIR ${CMAKE_BINARY_DIR})
|
||||
set(PYTHON_EXECUTABLE ${PYTHON_EXECUTABLE})
|
||||
pythonize_bool(LIBCXX_ENABLE_EXCEPTIONS)
|
||||
pythonize_bool(LIBCXX_ENABLE_RTTI)
|
||||
pythonize_bool(LIBCXX_ENABLE_SHARED)
|
||||
pythonize_bool(LIBCXX_BUILD_32_BITS)
|
||||
pythonize_bool(LIBCXX_ENABLE_THREADS)
|
||||
pythonize_bool(LIBCXX_ENABLE_MONOTONIC_CLOCK)
|
||||
|
||||
set(AUTO_GEN_COMMENT "## Autogenerated by libcxx configuration.\n# Do not edit!")
|
||||
|
||||
|
||||
352
test/lit.cfg
352
test/lit.cfg
@@ -29,30 +29,14 @@ class LibcxxTestFormat(lit.formats.FileBasedTest):
|
||||
"""
|
||||
|
||||
def __init__(self, cxx_under_test, use_verify_for_fail,
|
||||
cpp_flags, ld_flags, exec_env):
|
||||
cpp_flags, ld_flags, exec_env,
|
||||
use_ccache=False):
|
||||
self.cxx_under_test = cxx_under_test
|
||||
self.use_verify_for_fail = use_verify_for_fail
|
||||
self.cpp_flags = list(cpp_flags)
|
||||
self.ld_flags = list(ld_flags)
|
||||
self.exec_env = dict(exec_env)
|
||||
|
||||
def execute_command(self, command, in_dir=None):
|
||||
kwargs = {
|
||||
'stdin' :subprocess.PIPE,
|
||||
'stdout':subprocess.PIPE,
|
||||
'stderr':subprocess.PIPE,
|
||||
}
|
||||
if in_dir:
|
||||
kwargs['cwd'] = in_dir
|
||||
p = subprocess.Popen(command, **kwargs)
|
||||
out, err = p.communicate()
|
||||
exitCode = p.wait()
|
||||
|
||||
# Detect Ctrl-C in subprocess.
|
||||
if exitCode == -signal.SIGINT:
|
||||
raise KeyboardInterrupt
|
||||
|
||||
return out, err, exitCode
|
||||
self.use_ccache = use_ccache
|
||||
|
||||
def execute(self, test, lit_config):
|
||||
while True:
|
||||
@@ -108,22 +92,56 @@ class LibcxxTestFormat(lit.formats.FileBasedTest):
|
||||
# Evaluate the test.
|
||||
return self._evaluate_test(test, use_verify, lit_config)
|
||||
|
||||
def _build(self, exec_path, source_path, compile_only=False,
|
||||
use_verify=False):
|
||||
cmd = [self.cxx_under_test, '-o', exec_path,
|
||||
source_path] + self.cpp_flags
|
||||
|
||||
if compile_only:
|
||||
cmd += ['-c']
|
||||
else:
|
||||
cmd += self.ld_flags
|
||||
def _make_report(self, cmd, out, err, rc):
|
||||
report = "Command: %s\n" % cmd
|
||||
report += "Exit Code: %d\n" % rc
|
||||
if out:
|
||||
report += "Standard Output:\n--\n%s--\n" % out
|
||||
if err:
|
||||
report += "Standard Error:\n--\n%s--\n" % err
|
||||
report += '\n'
|
||||
return cmd, report, rc
|
||||
|
||||
def _compile(self, output_path, source_path, use_verify=False):
|
||||
cmd = [self.cxx_under_test, '-c', '-o', output_path, source_path]
|
||||
cmd += self.cpp_flags
|
||||
if use_verify:
|
||||
cmd += ['-Xclang', '-verify']
|
||||
|
||||
out, err, rc = self.execute_command(cmd)
|
||||
if self.use_ccache:
|
||||
cmd = ['ccache'] + cmd
|
||||
out, err, rc = lit.util.executeCommand(cmd)
|
||||
return cmd, out, err, rc
|
||||
|
||||
def _link(self, exec_path, object_path):
|
||||
cmd = [self.cxx_under_test, '-o', exec_path, object_path]
|
||||
cmd += self.cpp_flags + self.ld_flags
|
||||
out, err, rc = lit.util.executeCommand(cmd)
|
||||
return cmd, out, err, rc
|
||||
|
||||
def _compile_and_link(self, exec_path, source_path):
|
||||
object_file = tempfile.NamedTemporaryFile(suffix=".o", delete=False)
|
||||
object_path = object_file.name
|
||||
object_file.close()
|
||||
try:
|
||||
cmd, out, err, rc = self._compile(object_path, source_path)
|
||||
if rc != 0:
|
||||
return cmd, out, err, rc
|
||||
return self._link(exec_path, object_path)
|
||||
finally:
|
||||
try:
|
||||
os.remove(object_path)
|
||||
except:
|
||||
pass
|
||||
|
||||
def _build(self, exec_path, source_path, compile_only=False,
|
||||
use_verify=False):
|
||||
if compile_only:
|
||||
cmd, out, err, rc = self._compile(exec_path, source_path, use_verify)
|
||||
else:
|
||||
assert not use_verify
|
||||
cmd, out, err, rc = self._compile_and_link(exec_path, source_path)
|
||||
return self._make_report(cmd, out, err, rc)
|
||||
|
||||
def _clean(self, exec_path):
|
||||
os.remove(exec_path)
|
||||
|
||||
@@ -136,8 +154,8 @@ class LibcxxTestFormat(lit.formats.FileBasedTest):
|
||||
cmd.append(exec_path)
|
||||
if lit_config.useValgrind:
|
||||
cmd = lit_config.valgrindArgs + cmd
|
||||
out, err, exitCode = self.execute_command(cmd, in_dir)
|
||||
return cmd, out, err, exitCode
|
||||
out, err, rc = lit.util.executeCommand(cmd, cwd=in_dir)
|
||||
return self._make_report(cmd, out, err, rc)
|
||||
|
||||
def _evaluate_test(self, test, use_verify, lit_config):
|
||||
name = test.path_in_suite[-1]
|
||||
@@ -150,54 +168,31 @@ class LibcxxTestFormat(lit.formats.FileBasedTest):
|
||||
|
||||
# If this is a compile (failure) test, build it and check for failure.
|
||||
if expected_compile_fail:
|
||||
cmd, out, err, rc = self._build('/dev/null', source_path,
|
||||
cmd, report, rc = self._build('/dev/null', source_path,
|
||||
compile_only=True,
|
||||
use_verify=use_verify)
|
||||
expected_rc = 0 if use_verify else 1
|
||||
if rc == expected_rc:
|
||||
return lit.Test.PASS, ""
|
||||
else:
|
||||
report = """Command: %s\n""" % ' '.join(["'%s'" % a
|
||||
for a in cmd])
|
||||
report += """Exit Code: %d\n""" % rc
|
||||
if out:
|
||||
report += """Standard Output:\n--\n%s--""" % out
|
||||
if err:
|
||||
report += """Standard Error:\n--\n%s--""" % err
|
||||
report += "\n\nExpected compilation to fail!"
|
||||
return lit.Test.FAIL, report
|
||||
return lit.Test.FAIL, report + 'Expected compilation to fail!\n'
|
||||
else:
|
||||
exec_file = tempfile.NamedTemporaryFile(suffix="exe", delete=False)
|
||||
exec_path = exec_file.name
|
||||
exec_file.close()
|
||||
|
||||
try:
|
||||
cmd, out, err, rc = self._build(exec_path, source_path)
|
||||
cmd, report, rc = self._build(exec_path, source_path)
|
||||
compile_cmd = cmd
|
||||
if rc != 0:
|
||||
report = """Command: %s\n""" % ' '.join(["'%s'" % a
|
||||
for a in cmd])
|
||||
report += """Exit Code: %d\n""" % rc
|
||||
if out:
|
||||
report += """Standard Output:\n--\n%s--""" % out
|
||||
if err:
|
||||
report += """Standard Error:\n--\n%s--""" % err
|
||||
report += "\n\nCompilation failed unexpectedly!"
|
||||
report += "Compilation failed unexpectedly!"
|
||||
return lit.Test.FAIL, report
|
||||
|
||||
cmd, out, err, rc = self._run(exec_path, lit_config,
|
||||
cmd, report, rc = self._run(exec_path, lit_config,
|
||||
source_dir)
|
||||
if rc != 0:
|
||||
report = """Compiled With: %s\n""" % \
|
||||
' '.join(["'%s'" % a for a in compile_cmd])
|
||||
report += """Command: %s\n""" % \
|
||||
' '.join(["'%s'" % a for a in cmd])
|
||||
report += """Exit Code: %d\n""" % rc
|
||||
if out:
|
||||
report += """Standard Output:\n--\n%s--""" % out
|
||||
if err:
|
||||
report += """Standard Error:\n--\n%s--""" % err
|
||||
report += "\n\nCompiled test failed unexpectedly!"
|
||||
report = "Compiled With: %s\n%s" % (compile_cmd, report)
|
||||
report += "Compiled test failed unexpectedly!"
|
||||
return lit.Test.FAIL, report
|
||||
finally:
|
||||
try:
|
||||
@@ -329,12 +324,13 @@ class Configuration(object):
|
||||
self.cxx = None
|
||||
self.src_root = None
|
||||
self.obj_root = None
|
||||
self.library_root = None
|
||||
self.env = {}
|
||||
self.compile_flags = []
|
||||
self.library_paths = []
|
||||
self.link_flags = []
|
||||
self.use_system_lib = False
|
||||
self.use_clang_verify = False
|
||||
self.use_ccache = False
|
||||
|
||||
if platform.system() not in ('Darwin', 'FreeBSD', 'Linux'):
|
||||
self.lit_config.fatal("unrecognized system")
|
||||
@@ -347,10 +343,10 @@ class Configuration(object):
|
||||
val = default
|
||||
return val
|
||||
|
||||
def get_lit_bool(self, name):
|
||||
def get_lit_bool(self, name, default=None):
|
||||
conf = self.get_lit_conf(name)
|
||||
if conf is None:
|
||||
return None
|
||||
return default
|
||||
if conf.lower() in ('1', 'true'):
|
||||
return True
|
||||
if conf.lower() in ('', '0', 'false'):
|
||||
@@ -360,25 +356,34 @@ class Configuration(object):
|
||||
|
||||
def configure(self):
|
||||
self.configure_cxx()
|
||||
self.probe_cxx()
|
||||
self.configure_triple()
|
||||
self.configure_src_root()
|
||||
self.configure_obj_root()
|
||||
self.configure_library_root()
|
||||
self.configure_use_system_lib()
|
||||
self.configure_use_clang_verify()
|
||||
self.configure_ccache()
|
||||
self.configure_env()
|
||||
self.configure_std_flag()
|
||||
self.configure_compile_flags()
|
||||
self.configure_link_flags()
|
||||
self.configure_sanitizer()
|
||||
self.configure_features()
|
||||
# Print the final compile and link flags.
|
||||
self.lit_config.note('Using compile flags: %s' % self.compile_flags)
|
||||
self.lit_config.note('Using link flags: %s' % self.link_flags)
|
||||
# Print as list to prevent "set([...])" from being printed.
|
||||
self.lit_config.note('Using available_features: %s' %
|
||||
list(self.config.available_features))
|
||||
|
||||
def get_test_format(self):
|
||||
return LibcxxTestFormat(
|
||||
self.cxx,
|
||||
self.use_clang_verify,
|
||||
cpp_flags=['-nostdinc++'] + self.compile_flags,
|
||||
ld_flags=['-nodefaultlibs'] + self.link_flags,
|
||||
exec_env=self.env)
|
||||
cpp_flags=self.compile_flags,
|
||||
ld_flags=self.link_flags,
|
||||
exec_env=self.env,
|
||||
use_ccache=self.use_ccache)
|
||||
|
||||
def configure_cxx(self):
|
||||
# Gather various compiler parameters.
|
||||
@@ -397,6 +402,44 @@ class Configuration(object):
|
||||
self.lit_config.fatal('must specify user parameter cxx_under_test '
|
||||
'(e.g., --param=cxx_under_test=clang++)')
|
||||
|
||||
def probe_cxx(self):
|
||||
# Dump all of the predefined macros
|
||||
dump_macro_cmd = [self.cxx, '-dM', '-E', '-x', 'c++', '/dev/null']
|
||||
out, err, rc = lit.util.executeCommand(dump_macro_cmd)
|
||||
if rc != 0:
|
||||
self.lit_config.warning('Failed to dump macros for compiler: %s' %
|
||||
self.cxx)
|
||||
return
|
||||
# Create a dict containing all the predefined macros.
|
||||
macros = {}
|
||||
lines = [l.strip() for l in out.split('\n') if l.strip()]
|
||||
for l in lines:
|
||||
assert l.startswith('#define ')
|
||||
l = l[len('#define '):]
|
||||
macro, _, value = l.partition(' ')
|
||||
macros[macro] = value
|
||||
# Add compiler information to available features.
|
||||
compiler_name = None
|
||||
major_ver = minor_ver = None
|
||||
if '__clang__' in macros.keys():
|
||||
compiler_name = 'clang'
|
||||
# Treat apple's llvm fork differently.
|
||||
if '__apple_build_version__' in macros.keys():
|
||||
compiler_name = 'apple-clang'
|
||||
major_ver = macros['__clang_major__']
|
||||
minor_ver = macros['__clang_minor__']
|
||||
elif '__GNUC__' in macros.keys():
|
||||
compiler_name = 'gcc'
|
||||
major_ver = macros['__GNUC__']
|
||||
minor_ver = macros['__GNUC_MINOR__']
|
||||
else:
|
||||
self.lit_config.warning('Failed to detect compiler for cxx: %s' %
|
||||
self.cxx)
|
||||
if compiler_name is not None:
|
||||
self.config.available_features.add(compiler_name)
|
||||
self.config.available_features.add('%s-%s.%s' % (
|
||||
compiler_name, major_ver, minor_ver))
|
||||
|
||||
def configure_src_root(self):
|
||||
self.src_root = self.get_lit_conf(
|
||||
'libcxx_src_root', os.path.dirname(self.config.test_source_root))
|
||||
@@ -404,6 +447,9 @@ class Configuration(object):
|
||||
def configure_obj_root(self):
|
||||
self.obj_root = self.get_lit_conf('libcxx_obj_root', self.src_root)
|
||||
|
||||
def configure_library_root(self):
|
||||
self.library_root = self.get_lit_conf('libcxx_library_root', self.obj_root)
|
||||
|
||||
def configure_use_system_lib(self):
|
||||
# This test suite supports testing against either the system library or
|
||||
# the locally built one; the former mode is useful for testing ABI
|
||||
@@ -425,6 +471,11 @@ class Configuration(object):
|
||||
self.lit_config.note(
|
||||
"inferred use_clang_verify as: %r" % self.use_clang_verify)
|
||||
|
||||
def configure_ccache(self):
|
||||
self.use_ccache = self.get_lit_bool('use_ccache', False)
|
||||
if self.use_ccache:
|
||||
self.lit_config.note('enabling ccache')
|
||||
|
||||
def configure_features(self):
|
||||
additional_features = self.get_lit_conf('additional_features')
|
||||
if additional_features:
|
||||
@@ -486,34 +537,109 @@ class Configuration(object):
|
||||
self.config.available_features.add(
|
||||
'with_system_lib=%s' % self.config.target_triple)
|
||||
|
||||
if 'libcpp-has-no-threads' in self.config.available_features:
|
||||
self.compile_flags += ['-D_LIBCPP_HAS_NO_THREADS']
|
||||
# Some linux distributions have different locale data than others.
|
||||
# Insert the distributions name and name-version into the available
|
||||
# features to allow tests to XFAIL on them.
|
||||
if sys.platform.startswith('linux'):
|
||||
name, ver, _ = platform.linux_distribution()
|
||||
name = name.lower().strip()
|
||||
ver = ver.lower().strip()
|
||||
if name:
|
||||
self.config.available_features.add(name)
|
||||
if name and ver:
|
||||
self.config.available_features.add('%s-%s' % (name, ver))
|
||||
|
||||
if 'libcpp-has-no-monotonic-clock' in self.config.available_features:
|
||||
self.compile_flags += ['-D_LIBCPP_HAS_NO_MONOTONIC_CLOCK']
|
||||
# Simulator testing can take a really long time for some of these tests
|
||||
# so add a feature check so we can REQUIRES: long_tests in them
|
||||
self.long_tests = self.get_lit_bool('long_tests')
|
||||
if self.long_tests is None:
|
||||
# Default to running long tests.
|
||||
self.long_tests = True
|
||||
self.lit_config.note(
|
||||
"inferred long_tests as: %r" % self.long_tests)
|
||||
|
||||
if self.long_tests:
|
||||
self.config.available_features.add('long_tests')
|
||||
|
||||
def configure_compile_flags(self):
|
||||
# Configure extra compiler flags.
|
||||
self.compile_flags += ['-I' + self.src_root + '/include',
|
||||
'-I' + self.src_root + '/test/support']
|
||||
# Try and get the std version from the command line. Fall back to
|
||||
# default given in lit.site.cfg is not present. If default is not
|
||||
# present then force c++11.
|
||||
std = self.get_lit_conf('std', 'c++11')
|
||||
self.compile_flags += ['-std={0}'.format(std)]
|
||||
self.config.available_features.add(std)
|
||||
# Configure include paths
|
||||
self.compile_flags += ['-nostdinc++']
|
||||
self.compile_flags += ['-I' + self.src_root + '/test/support']
|
||||
libcxx_headers = self.get_lit_conf('libcxx_headers',
|
||||
self.src_root + '/include')
|
||||
if not os.path.isdir(libcxx_headers):
|
||||
self.lit_config.fatal("libcxx_headers='%s' is not a directory."
|
||||
% libcxx_headers)
|
||||
self.compile_flags += ['-I' + libcxx_headers]
|
||||
if sys.platform.startswith('linux'):
|
||||
self.compile_flags += ['-D__STDC_FORMAT_MACROS',
|
||||
'-D__STDC_LIMIT_MACROS',
|
||||
'-D__STDC_CONSTANT_MACROS']
|
||||
# Configure feature flags.
|
||||
enable_exceptions = self.get_lit_bool('enable_exceptions', True)
|
||||
if enable_exceptions:
|
||||
self.config.available_features.add('exceptions')
|
||||
else:
|
||||
self.compile_flags += ['-fno-exceptions']
|
||||
enable_rtti = self.get_lit_bool('enable_rtti', True)
|
||||
if enable_rtti:
|
||||
self.config.available_features.add('rtti')
|
||||
else:
|
||||
self.compile_flags += ['-fno-rtti', '-D_LIBCPP_NO_RTTI']
|
||||
enable_32bit = self.get_lit_bool('enable_32bit', False)
|
||||
if enable_32bit:
|
||||
self.compile_flags += ['-m32']
|
||||
# Configure threading features.
|
||||
enable_threads = self.get_lit_bool('enable_threads', True)
|
||||
enable_monotonic_clock = self.get_lit_bool('enable_monotonic_clock', True)
|
||||
if not enable_threads:
|
||||
self.compile_flags += ['-D_LIBCPP_HAS_NO_THREADS']
|
||||
self.config.available_features.add('libcpp-has-no-threads')
|
||||
if not enable_monotonic_clock:
|
||||
self.compile_flags += ['-D_LIBCPP_HAS_NO_MONOTONIC_CLOCK']
|
||||
self.config.available_features.add('libcpp-has-no-monotonic-clock')
|
||||
elif not enable_monotonic_clock:
|
||||
self.lit_config.fatal('enable_monotonic_clock cannot be false when'
|
||||
' enable_threads is true.')
|
||||
# Use verbose output for better errors
|
||||
self.compile_flags += ['-v']
|
||||
# Configure extra compile flags.
|
||||
compile_flags_str = self.get_lit_conf('compile_flags', '')
|
||||
self.compile_flags += shlex.split(compile_flags_str)
|
||||
|
||||
|
||||
def configure_link_flags(self):
|
||||
# Configure library search paths
|
||||
self.link_flags += ['-nodefaultlibs']
|
||||
libcxx_library = self.get_lit_conf('libcxx_library')
|
||||
# Configure libc++ library paths.
|
||||
if libcxx_library is not None:
|
||||
# Check that the given value for libcxx_library is valid.
|
||||
if not os.path.isfile(libcxx_library):
|
||||
self.lit_config.fatal(
|
||||
"libcxx_library='%s' is not a valid file." % libcxx_library)
|
||||
if self.use_system_lib:
|
||||
self.lit_config.fatal("Conflicting options: 'libcxx_library'"
|
||||
" cannot be used with 'use_system_lib=true'")
|
||||
self.link_flags += ['-Wl,-rpath,' + os.path.dirname(libcxx_library)]
|
||||
elif not self.use_system_lib:
|
||||
self.link_flags += ['-L' + self.library_root,
|
||||
'-Wl,-rpath,' + self.library_root]
|
||||
# Configure ABI library paths.
|
||||
abi_library_path = self.get_lit_conf('abi_library_path', '')
|
||||
self.link_flags += ['-L' + self.obj_root + '/lib']
|
||||
if not self.use_system_lib:
|
||||
self.link_flags += ['-Wl,-rpath', '-Wl,' + self.obj_root + '/lib']
|
||||
if abi_library_path:
|
||||
self.link_flags += ['-L' + abi_library_path,
|
||||
'-Wl,-rpath', '-Wl,' + abi_library_path]
|
||||
'-Wl,-rpath,' + abi_library_path]
|
||||
# Configure libraries
|
||||
if libcxx_library:
|
||||
self.link_flags += [libcxx_library]
|
||||
else:
|
||||
self.link_flags += ['-lc++']
|
||||
link_flags_str = self.get_lit_conf('link_flags')
|
||||
if link_flags_str is None:
|
||||
cxx_abi = self.get_lit_conf('cxx_abi', 'libcxxabi')
|
||||
if cxx_abi == 'libstdc++':
|
||||
self.link_flags += ['-lstdc++']
|
||||
@@ -528,7 +654,7 @@ class Configuration(object):
|
||||
else:
|
||||
self.lit_config.fatal(
|
||||
'C++ ABI setting %s unsupported for tests' % cxx_abi)
|
||||
|
||||
# Configure extra libraries.
|
||||
if sys.platform == 'darwin':
|
||||
self.link_flags += ['-lSystem']
|
||||
elif sys.platform.startswith('linux'):
|
||||
@@ -539,25 +665,12 @@ class Configuration(object):
|
||||
else:
|
||||
self.lit_config.fatal("unrecognized system: %r" % sys.platform)
|
||||
|
||||
self.lit_config.note(
|
||||
"inferred link_flags as: %r" % self.link_flags)
|
||||
if link_flags_str:
|
||||
link_flags_str = self.get_lit_conf('link_flags', '')
|
||||
self.link_flags += shlex.split(link_flags_str)
|
||||
|
||||
|
||||
def configure_std_flag(self):
|
||||
# Try and get the std version from the command line. Fall back to
|
||||
# default given in lit.site.cfg is not present. If default is not
|
||||
# present then force c++11.
|
||||
std = self.get_lit_conf('std')
|
||||
if std is None:
|
||||
std = 'c++11'
|
||||
self.lit_config.note('using default std: \'-std=c++11\'')
|
||||
self.compile_flags += ['-std={0}'.format(std)]
|
||||
self.config.available_features.add(std)
|
||||
|
||||
def configure_sanitizer(self):
|
||||
san = self.get_lit_conf('llvm_use_sanitizer', '').strip()
|
||||
san = self.get_lit_conf('use_sanitizer', '').strip()
|
||||
if san:
|
||||
# Search for llvm-symbolizer along the compiler path first
|
||||
# and then along the PATH env variable.
|
||||
@@ -622,12 +735,13 @@ class Configuration(object):
|
||||
"inferred target_triple as: %r" % self.config.target_triple)
|
||||
|
||||
def configure_env(self):
|
||||
# Configure extra linker parameters.
|
||||
if sys.platform == 'darwin':
|
||||
if not self.use_system_lib:
|
||||
self.env['DYLD_LIBRARY_PATH'] = os.path.join(self.obj_root,
|
||||
'lib')
|
||||
|
||||
if sys.platform == 'darwin' and not self.use_system_lib:
|
||||
libcxx_library = self.get_lit_conf('libcxx_library')
|
||||
if libcxx_library:
|
||||
library_root = os.path.dirname(libcxx_library)
|
||||
else:
|
||||
library_root = self.library_root
|
||||
self.env['DYLD_LIBRARY_PATH'] = library_root
|
||||
|
||||
def mm(path, android_build_top):
|
||||
env = os.environ
|
||||
@@ -703,6 +817,34 @@ config.suffixes = ['.cpp']
|
||||
# test_source_root: The root path where tests are located.
|
||||
config.test_source_root = os.path.dirname(__file__)
|
||||
|
||||
# Infer the test_exec_root from the libcxx_object root.
|
||||
libcxx_obj_root = getattr(config, 'libcxx_obj_root', None)
|
||||
if libcxx_obj_root is not None:
|
||||
config.test_exec_root = os.path.join(libcxx_obj_root, 'test')
|
||||
|
||||
# Check that the test exec root is known.
|
||||
if config.test_exec_root is None:
|
||||
# Otherwise, we haven't loaded the site specific configuration (the user is
|
||||
# probably trying to run on a test file directly, and either the site
|
||||
# configuration hasn't been created by the build system, or we are in an
|
||||
# out-of-tree build situation).
|
||||
site_cfg = lit_config.params.get('libcxx_site_config',
|
||||
os.environ.get('LIBCXX_SITE_CONFIG'))
|
||||
if not site_cfg:
|
||||
lit_config.warning('No site specific configuration file found!'
|
||||
' Running the tests in the default configuration.')
|
||||
# TODO: Set test_exec_root to a temporary directory where output files
|
||||
# can be placed. This is needed for ShTest.
|
||||
elif not os.path.isfile(site_cfg):
|
||||
lit_config.fatal(
|
||||
"Specified site configuration file does not exist: '%s'" %
|
||||
site_cfg)
|
||||
else:
|
||||
lit_config.note('using site specific configuration at %s' % site_cfg)
|
||||
lit_config.load_config(config, site_cfg)
|
||||
raise SystemExit()
|
||||
|
||||
|
||||
cfg_variant = getattr(config, 'configuration_variant', '')
|
||||
if cfg_variant:
|
||||
print 'Using configuration variant: %s' % cfg_variant
|
||||
|
||||
@@ -3,10 +3,15 @@ config.cxx_under_test = "@LIBCXX_COMPILER@"
|
||||
config.std = "@LIBCXX_STD_VERSION@"
|
||||
config.libcxx_src_root = "@LIBCXX_SOURCE_DIR@"
|
||||
config.libcxx_obj_root = "@LIBCXX_BINARY_DIR@"
|
||||
config.python_executable = "@PYTHON_EXECUTABLE@"
|
||||
config.enable_shared = @LIBCXX_ENABLE_SHARED@
|
||||
config.libcxx_library_root = "@LIBCXX_LIBRARY_DIR@"
|
||||
config.enable_exceptions = "@LIBCXX_ENABLE_EXCEPTIONS@"
|
||||
config.enable_rtti = "@LIBCXX_ENABLE_RTTI@"
|
||||
config.enable_shared = "@LIBCXX_ENABLE_SHARED@"
|
||||
config.enable_32bit = "@LIBCXX_BUILD_32_BITS@"
|
||||
config.enable_threads = "@LIBCXX_ENABLE_THREADS@"
|
||||
config.enable_monotonic_clock = "@LIBCXX_ENABLE_MONOTONIC_CLOCK@"
|
||||
config.cxx_abi = "@LIBCXX_CXX_ABI_LIBNAME@"
|
||||
config.llvm_use_sanitizer = "@LLVM_USE_SANITIZER@"
|
||||
config.use_sanitizer = "@LLVM_USE_SANITIZER@"
|
||||
config.abi_library_path = "@LIBCXX_CXX_ABI_LIBRARY_PATH@"
|
||||
|
||||
# Let the main config do the real work.
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// <random>
|
||||
|
||||
// class random_device;
|
||||
|
||||
// explicit random_device(const string& token = "/dev/urandom");
|
||||
|
||||
#include <random>
|
||||
#include <cassert>
|
||||
#include <unistd.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
try
|
||||
{
|
||||
std::random_device r("wrong file");
|
||||
assert(false);
|
||||
}
|
||||
catch (const std::system_error& e)
|
||||
{
|
||||
}
|
||||
{
|
||||
std::random_device r;
|
||||
}
|
||||
{
|
||||
int ec;
|
||||
ec = close(STDIN_FILENO);
|
||||
assert(!ec);
|
||||
ec = close(STDOUT_FILENO);
|
||||
assert(!ec);
|
||||
ec = close(STDERR_FILENO);
|
||||
assert(!ec);
|
||||
std::random_device r;
|
||||
}
|
||||
{
|
||||
std::random_device r("/dev/urandom");;
|
||||
}
|
||||
{
|
||||
std::random_device r("/dev/random");;
|
||||
}
|
||||
}
|
||||
@@ -62,6 +62,53 @@ test1()
|
||||
|
||||
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
||||
|
||||
void test2()
|
||||
{
|
||||
{
|
||||
int src[2][2] = {{0, 1}, {2, 3}};
|
||||
decltype(src) dest = {{9, 8}, {7, 6}};
|
||||
|
||||
std::swap(src, dest);
|
||||
|
||||
assert ( src[0][0] == 9 );
|
||||
assert ( src[0][1] == 8 );
|
||||
assert ( src[1][0] == 7 );
|
||||
assert ( src[1][1] == 6 );
|
||||
|
||||
assert ( dest[0][0] == 0 );
|
||||
assert ( dest[0][1] == 1 );
|
||||
assert ( dest[1][0] == 2 );
|
||||
assert ( dest[1][1] == 3 );
|
||||
}
|
||||
|
||||
{
|
||||
int src[3][3] = {{0, 1, 2}, {3, 4, 5}, {6, 7, 8}};
|
||||
decltype(src) dest = {{9, 8, 7}, {6, 5, 4}, {3, 2, 1}};
|
||||
|
||||
std::swap(src, dest);
|
||||
|
||||
assert ( src[0][0] == 9 );
|
||||
assert ( src[0][1] == 8 );
|
||||
assert ( src[0][2] == 7 );
|
||||
assert ( src[1][0] == 6 );
|
||||
assert ( src[1][1] == 5 );
|
||||
assert ( src[1][2] == 4 );
|
||||
assert ( src[2][0] == 3 );
|
||||
assert ( src[2][1] == 2 );
|
||||
assert ( src[2][2] == 1 );
|
||||
|
||||
assert ( dest[0][0] == 0 );
|
||||
assert ( dest[0][1] == 1 );
|
||||
assert ( dest[0][2] == 2 );
|
||||
assert ( dest[1][0] == 3 );
|
||||
assert ( dest[1][1] == 4 );
|
||||
assert ( dest[1][2] == 5 );
|
||||
assert ( dest[2][0] == 6 );
|
||||
assert ( dest[2][1] == 7 );
|
||||
assert ( dest[2][2] == 8 );
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test<forward_iterator<int*>, forward_iterator<int*> >();
|
||||
@@ -107,4 +154,6 @@ int main()
|
||||
test1<std::unique_ptr<int>*, std::unique_ptr<int>*>();
|
||||
|
||||
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
||||
|
||||
test2();
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user