注意:
使用 C++ 11/14 标准以上应注释下述代码并恢复上述被注释的代码,即设置编译器选项标准为:-std=cxx1z、-std=cxx2a。
// C++ 17...cxx1z
//template <class _Iter>
//constexpr void* _Voidify_iter(_Iter _It) noexcept {
// if constexpr (std::is_pointer<_Iter>::value) {
// return const_cast<void*>(static_cast<const volatile void*>(_It));
// }
// else {
// return const_cast<void*>(static_cast<const volatile void*>(std::addressof(*_It)));
// }
//}
// C++ 11...cxx0x
// C++ 14...cxx1y
template <typename _Iter>
typename std::enable_if<std::is_pointer<_Iter>::value, void*>::type
constexpr _Voidify_iter(_Iter _It) noexcept {
return const_cast<void*>(static_cast<const volatile void*>(_It));
}
template <typename _Iter>
typename std::enable_if<!std::is_pointer<_Iter>::value, void*>::type
constexpr _Voidify_iter(_Iter _It) noexcept {
return const_cast<void*>(static_cast<const volatile void*>(std::addressof(*_It)));
}
当然你可以选择判定编译器宏:__cplusplus
if (__cplusplus == 201703L)
std::cout << "C++17\n";
else if (__cplusplus == 201402L)
std::cout << "C++14\n";
else if (__cplusplus == 201103L)
std::cout << "C++11\n";
else if (__cplusplus == 199711L)
std::cout << "C++98\n";
else if (__cplusplus == 202002L)
std::cout << "C++20\n";
else
std::cout << "pre-standard C++\n";
头文件定义:
template <class _Ty>
class allocator {
public:
static_assert(!std::is_const<_Ty>::value, "The C++ Standard forbids containers of const elements "
"because allocator<const T> is ill-formed.");
using _From_primary = allocator;
using value_type = _Ty;
using pointer = _Ty*;
using const_pointer = const _Ty*;
using reference = _Ty&;
using const_reference = const _Ty&;
using size_type = size_t;
using difference_type = ptrdiff_t;
using propagate_on_container_move_assignment = std::true_type;
using is_always_equal = std::true_type;
template <class _Other>
struct rebind {
using other = allocator<_Other>;
};
_Ty* address(_Ty& _Val) const noexcept {
return std::addressof(_Val);
}
const _Ty* address(const _Ty& _Val) const noexcept {
return std::addressof(_Val);
}
constexpr allocator() noexcept {}
constexpr allocator(const allocator&) noexcept = default;
template <class _Other>
constexpr allocator(const allocator<_Other>&) noexcept {}
~allocator() = default;
allocator& operator=(const allocator&) = default;
void deallocate(_Ty* const _Ptr, const size_t _Count) {
assert((_Ptr != nullptr || _Count == 0) && "null pointer cannot point to a block of non-zero size");
// no overflow check on the following multiply; we assume _Allocate did that check
ppp::Mfree(_Ptr);
}
_Ty* allocate(const size_t _Count) {
static_assert(sizeof(value_type) > 0, "value_type must be complete before calling allocate.");
void* memory = (void*)ppp::Malloc(sizeof(_Ty) * _Count);
return static_cast<_Ty*>(memory);
}
_Ty* allocate(const size_t _Count, const void*) {
return allocate(_Count);
}
// C++ 17...cxx1z
//template <class _Iter>
//constexpr void* _Voidify_iter(_Iter _It) noexcept {
// if constexpr (std::is_pointer<_Iter>::value) {
// return const_cast<void*>(static_cast<const volatile void*>(_It));
// }
// else {
// return const_cast<void*>(static_cast<const volatile void*>(std::addressof(*_It)));
// }
//}
// C++ 11...cxx0x
// C++ 14...cxx1y
template <typename _Iter>
typename std::enable_if<std::is_pointer<_Iter>::value, void*>::type
constexpr _Voidify_iter(_Iter _It) noexcept {
return const_cast<void*>(static_cast<const volatile void*>(_It));
}
template <typename _Iter>
typename std::enable_if<!std::is_pointer<_Iter>::value, void*>::type
constexpr _Voidify_iter(_Iter _It) noexcept {
return const_cast<void*>(static_cast<const volatile void*>(std::addressof(*_It)));
}
template <class _Objty, class... _Types>
void construct(_Objty* const _Ptr, _Types&&... _Args) {
::new (_Voidify_iter(_Ptr)) _Objty(std::forward<_Types>(_Args)...);
}
template <class _Uty>
void destroy(_Uty* const _Ptr) {
_Ptr->~_Uty();
}
size_t max_size() const noexcept {
return static_cast<size_t>(-1) / sizeof(_Ty);
}
// The number of user bytes a single byte of ASAN shadow memory can track.
static constexpr size_t _Asan_granularity = 8;
static constexpr size_t _Minimum_allocation_alignment = _Asan_granularity;
};
using string = std::basic_string<char, std::char_traits<char>, allocator<char>>;
template <typename TValue>
using list = std::list<TValue, allocator<TValue>>;
template <typename TValue>
using vector = std::vector<TValue, allocator<TValue>>;
template <typename TValue>
using set = std::set<TValue, std::less<TValue>, allocator<TValue>>;
template <typename TKey, typename TValue>
using map = std::map<TKey, TValue, std::less<TKey>, allocator<std::pair<const TKey, TValue>>>;
template <typename TValue>
using unordered_set = std::unordered_set<TValue, std::hash<TValue>, std::equal_to<TValue>, allocator<TValue>>;
template <typename TKey, typename TValue>
using unordered_map = std::unordered_map<TKey, TValue, std::hash<TKey>, std::equal_to<TKey>, allocator<std::pair<const TKey, TValue>>>;