Reworked to_string test to verify the overload with a custom allocator even when explicit conversion operators are not supported. Made the custom allocator more standard-compliant.

This commit is contained in:
Andrey Semashev 2016-09-01 22:42:29 +03:00
parent 4814d1ebfe
commit 3d853b0e83

View File

@ -7,13 +7,14 @@
For more information, see http://www.boost.org
*/
#include <new> // for placement new
#include <iostream>
#include <cstring> // for std::strchr
#ifndef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS
#include <cstddef> // for NULL, std::size_t, std::ptrdiff_t
#include <cstring> // for std::strchr and std::strcmp
#include <cstdlib> // for std::malloc and std::free
#endif
#include <boost/utility/string_view.hpp>
#include <boost/config.hpp>
#define BOOST_TEST_MAIN
#include <boost/test/unit_test.hpp>
@ -244,29 +245,86 @@ void find ( const char *arg ) {
}
#ifndef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS
template <typename T>
class alloc_holder{
class custom_allocator {
public:
typedef T value_type;
explicit alloc_holder(){}
T *allocate(std::size_t n){
return reinterpret_cast<T *>(std::malloc(sizeof(T) * n));
typedef T* pointer;
typedef const T* const_pointer;
typedef void* void_pointer;
typedef const void* const_void_pointer;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
typedef T& reference;
typedef const T& const_reference;
template<class U>
struct rebind {
typedef custom_allocator<U> other;
};
custom_allocator() BOOST_NOEXCEPT {}
template <typename U>
custom_allocator(custom_allocator<U> const&) BOOST_NOEXCEPT {}
pointer allocate(size_type n) const {
return static_cast<pointer>(std::malloc(sizeof(value_type) * n));
}
void deallocate(T *p, std::size_t n){
void deallocate(pointer p, size_type) const BOOST_NOEXCEPT {
std::free(p);
}
pointer address(reference value) const BOOST_NOEXCEPT {
return &value;
}
const_pointer address(const_reference value) const BOOST_NOEXCEPT {
return &value;
}
BOOST_CONSTEXPR size_type max_size() const BOOST_NOEXCEPT {
return (~(size_type)0u) / sizeof(value_type);
}
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template <class U, class... Args>
void construct(U* ptr, Args&&... args) const {
::new((void*)ptr) U(static_cast<Args&&>(args)...);
}
#else
template <class U, class V>
void construct(U* ptr, V&& value) const {
::new((void*)ptr) U(static_cast<V&&>(value));
}
#endif
#else
template <class U, class V>
void construct(U* ptr, const V& value) const {
::new((void*)ptr) U(value);
}
#endif
template <class U>
void construct(U* ptr) const {
::new((void*)ptr) U();
}
template <class U>
void destroy(U* ptr) const {
(void)ptr;
ptr->~U();
}
};
template <typename T, typename U>
bool operator==(const alloc_holder<T> &, const alloc_holder<U> &){
BOOST_CONSTEXPR bool operator==(const custom_allocator<T> &, const custom_allocator<U> &) BOOST_NOEXCEPT {
return true;
}
template <typename T, typename U>
bool operator!=(const alloc_holder<T> &, const alloc_holder<U> &){
BOOST_CONSTEXPR bool operator!=(const custom_allocator<T> &, const custom_allocator<U> &) BOOST_NOEXCEPT {
return false;
}
#endif
void to_string ( const char *arg ) {
string_view sr1;
@ -279,11 +337,12 @@ void to_string ( const char *arg ) {
str2 = sr1.to_string ();
BOOST_CHECK ( str1 == str2 );
#ifndef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS
std::string str3 = static_cast<std::string> ( sr1 );
BOOST_CHECK ( str1 == str3 );
std::basic_string<char, std::char_traits<char>, custom_allocator<char> > str3 = sr1.to_string(custom_allocator<char>());
BOOST_CHECK ( std::strcmp(str1.c_str(), str3.c_str()) == 0 );
std::basic_string<char, std::char_traits<char>, alloc_holder<char>> alloc_str = sr1.to_string(alloc_holder<char>());
#ifndef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS
std::string str4 = static_cast<std::string> ( sr1 );
BOOST_CHECK ( str1 == str4 );
#endif
}