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 For more information, see http://www.boost.org
*/ */
#include <new> // for placement new
#include <iostream> #include <iostream>
#include <cstring> // for std::strchr #include <cstddef> // for NULL, std::size_t, std::ptrdiff_t
#ifndef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS #include <cstring> // for std::strchr and std::strcmp
#include <cstdlib> // for std::malloc and std::free #include <cstdlib> // for std::malloc and std::free
#endif
#include <boost/utility/string_view.hpp> #include <boost/utility/string_view.hpp>
#include <boost/config.hpp>
#define BOOST_TEST_MAIN #define BOOST_TEST_MAIN
#include <boost/test/unit_test.hpp> #include <boost/test/unit_test.hpp>
@ -86,7 +87,7 @@ void reverse ( const char *arg ) {
BOOST_CHECK ( std::equal ( sr1.begin (), sr1.end (), string2.begin ())); BOOST_CHECK ( std::equal ( sr1.begin (), sr1.end (), string2.begin ()));
} }
// This helper function eliminates signed vs. unsigned warnings // This helper function eliminates signed vs. unsigned warnings
string_view::size_type ptr_diff ( const char *res, const char *base ) { string_view::size_type ptr_diff ( const char *res, const char *base ) {
BOOST_CHECK ( res >= base ); BOOST_CHECK ( res >= base );
return static_cast<string_view::size_type> ( res - base ); return static_cast<string_view::size_type> ( res - base );
@ -115,7 +116,7 @@ void find ( const char *arg ) {
++p; ++p;
} }
// Look for pairs on characters (searching from the start) // Look for pairs on characters (searching from the start)
sr1 = arg; sr1 = arg;
p = arg; p = arg;
while ( *p && *(p+1)) { while ( *p && *(p+1)) {
@ -244,29 +245,86 @@ void find ( const char *arg ) {
} }
#ifndef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS
template <typename T> template <typename T>
class alloc_holder{ class custom_allocator {
public: public:
typedef T value_type; typedef T value_type;
explicit alloc_holder(){} typedef T* pointer;
T *allocate(std::size_t n){ typedef const T* const_pointer;
return reinterpret_cast<T *>(std::malloc(sizeof(T) * n)); typedef void* void_pointer;
} typedef const void* const_void_pointer;
void deallocate(T *p, std::size_t n){ 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(pointer p, size_type) const BOOST_NOEXCEPT {
std::free(p); 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> 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; return true;
} }
template <typename T, typename 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 false; return false;
} }
#endif
void to_string ( const char *arg ) { void to_string ( const char *arg ) {
string_view sr1; string_view sr1;
@ -275,15 +333,16 @@ void to_string ( const char *arg ) {
str1.assign ( arg ); str1.assign ( arg );
sr1 = arg; sr1 = arg;
// str2 = sr1.to_string<std::allocator<char> > (); // str2 = sr1.to_string<std::allocator<char> > ();
str2 = sr1.to_string (); str2 = sr1.to_string ();
BOOST_CHECK ( str1 == str2 ); BOOST_CHECK ( str1 == str2 );
#ifndef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS std::basic_string<char, std::char_traits<char>, custom_allocator<char> > str3 = sr1.to_string(custom_allocator<char>());
std::string str3 = static_cast<std::string> ( sr1 ); BOOST_CHECK ( std::strcmp(str1.c_str(), str3.c_str()) == 0 );
BOOST_CHECK ( str1 == str3 );
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 #endif
} }
@ -294,11 +353,11 @@ void compare ( const char *arg ) {
str1.assign ( arg ); str1.assign ( arg );
sr1 = arg; sr1 = arg;
BOOST_CHECK ( sr1 == sr1); // compare string_view and string_view BOOST_CHECK ( sr1 == sr1); // compare string_view and string_view
BOOST_CHECK ( sr1 == str1); // compare string and string_view BOOST_CHECK ( sr1 == str1); // compare string and string_view
BOOST_CHECK ( str1 == sr1 ); // compare string_view and string BOOST_CHECK ( str1 == sr1 ); // compare string_view and string
BOOST_CHECK ( sr1 == arg ); // compare string_view and pointer BOOST_CHECK ( sr1 == arg ); // compare string_view and pointer
BOOST_CHECK ( arg == sr1 ); // compare pointer and string_view BOOST_CHECK ( arg == sr1 ); // compare pointer and string_view
if ( sr1.size () > 0 ) { if ( sr1.size () > 0 ) {
(*str1.rbegin())++; (*str1.rbegin())++;