From a23a903f9a36c082c0f5d10f574d264d6a5d7b83 Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Wed, 12 Aug 2020 02:12:04 -0400 Subject: [PATCH] Support the C++ allocator model (#103) --- include/boost/numeric/ublas/matrix.hpp | 8 +-- include/boost/numeric/ublas/storage.hpp | 47 +++++------------ .../boost/numeric/ublas/storage_sparse.hpp | 4 +- include/boost/numeric/ublas/vector.hpp | 12 ++--- test/Jamfile | 1 + test/minimal_allocator_test.cpp | 51 +++++++++++++++++++ 6 files changed, 76 insertions(+), 47 deletions(-) create mode 100644 test/minimal_allocator_test.cpp diff --git a/include/boost/numeric/ublas/matrix.hpp b/include/boost/numeric/ublas/matrix.hpp index 6e405d849..c2ac1958f 100644 --- a/include/boost/numeric/ublas/matrix.hpp +++ b/include/boost/numeric/ublas/matrix.hpp @@ -3460,8 +3460,8 @@ namespace boost { namespace numeric { #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS using matrix_container::operator (); #endif - typedef typename ALLOC::size_type size_type; - typedef typename ALLOC::difference_type difference_type; + typedef typename boost::allocator_size_type::type size_type; + typedef typename boost::allocator_difference_type::type difference_type; typedef T value_type; typedef const T &const_reference; typedef T &reference; @@ -3935,8 +3935,8 @@ namespace boost { namespace numeric { #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS using matrix_container::operator (); #endif - typedef typename ALLOC::size_type size_type; - typedef typename ALLOC::difference_type difference_type; + typedef typename boost::allocator_size_type::type size_type; + typedef typename boost::allocator_difference_type::type difference_type; typedef T value_type; typedef const T &const_reference; typedef T &reference; diff --git a/include/boost/numeric/ublas/storage.hpp b/include/boost/numeric/ublas/storage.hpp index fd0c58d24..4f7365248 100644 --- a/include/boost/numeric/ublas/storage.hpp +++ b/include/boost/numeric/ublas/storage.hpp @@ -18,6 +18,7 @@ #include #endif +#include #include #include #include @@ -45,8 +46,8 @@ namespace boost { namespace numeric { namespace ublas { typedef unbounded_array self_type; public: typedef ALLOC allocator_type; - typedef typename ALLOC::size_type size_type; - typedef typename ALLOC::difference_type difference_type; + typedef typename boost::allocator_size_type::type size_type; + typedef typename boost::allocator_difference_type::type difference_type; typedef T value_type; typedef const T &const_reference; typedef T &reference; @@ -76,11 +77,7 @@ namespace boost { namespace numeric { namespace ublas { #pragma warning(pop) #endif for (pointer d = data_; d != data_ + size_; ++d) -#if __cplusplus >= 201703L - std::allocator_traits::construct (alloc_, d, value_type()); -#else - alloc_.construct(d, value_type()); -#endif + boost::allocator_construct(alloc_, d); } } else @@ -153,29 +150,17 @@ namespace boost { namespace numeric { namespace ublas { pointer di = data_; if (size < size_) { for (; di != data_ + size; ++di) { -#if __cplusplus >= 201703L - std::allocator_traits::construct (alloc_, di, *si); -#else - alloc_.construct (di, *si); -#endif + boost::allocator_construct(alloc_, di, *si); ++si; } } else { for (; si != p_data + size_; ++si) { -#if __cplusplus >= 201703L - std::allocator_traits::construct (alloc_, di, *si); -#else - alloc_.construct (di, *si); -#endif + boost::allocator_construct(alloc_, di, *si); ++di; } for (; di != data_ + size; ++di) { -#if __cplusplus >= 201703L - std::allocator_traits::construct (alloc_, di, init); -#else - alloc_.construct (di, init); -#endif + boost::allocator_construct(alloc_, di, init); } } } @@ -190,11 +175,7 @@ namespace boost { namespace numeric { namespace ublas { #pragma warning(pop) #endif for (pointer di = data_; di != data_ + size; ++di) -#if __cplusplus >= 201703L - std::allocator_traits::construct(alloc_, di, value_type()); -#else - alloc_.construct (di, value_type()); -#endif + boost::allocator_construct(alloc_, di); } } } @@ -210,11 +191,7 @@ namespace boost { namespace numeric { namespace ublas { #pragma warning(pop) #endif for (pointer si = p_data; si != p_data + size_; ++si) -#if __cplusplus >= 201703L - std::allocator_traits::destroy (alloc_, si); -#else - alloc_.destroy (si); -#endif + boost::allocator_destroy(alloc_, si); } alloc_.deallocate (p_data, size_); } @@ -237,7 +214,7 @@ namespace boost { namespace numeric { namespace ublas { // Random Access Container BOOST_UBLAS_INLINE size_type max_size () const { - return ALLOC ().max_size(); + return boost::allocator_max_size(alloc_); } BOOST_UBLAS_INLINE @@ -385,8 +362,8 @@ namespace boost { namespace numeric { namespace ublas { typedef bounded_array self_type; public: // No allocator_type as ALLOC is not used for allocation - typedef typename ALLOC::size_type size_type; - typedef typename ALLOC::difference_type difference_type; + typedef typename boost::allocator_size_type::type size_type; + typedef typename boost::allocator_difference_type::type difference_type; typedef T value_type; typedef const T &const_reference; typedef T &reference; diff --git a/include/boost/numeric/ublas/storage_sparse.hpp b/include/boost/numeric/ublas/storage_sparse.hpp index f87685c79..eae3bc58f 100644 --- a/include/boost/numeric/ublas/storage_sparse.hpp +++ b/include/boost/numeric/ublas/storage_sparse.hpp @@ -214,8 +214,8 @@ namespace boost { namespace numeric { namespace ublas { class map_array { public: typedef ALLOC allocator_type; - typedef typename ALLOC::size_type size_type; - typedef typename ALLOC::difference_type difference_type; + typedef typename boost::allocator_size_type::type size_type; + typedef typename boost::allocator_difference_type::type difference_type; typedef std::pair value_type; typedef I key_type; typedef T mapped_type; diff --git a/include/boost/numeric/ublas/vector.hpp b/include/boost/numeric/ublas/vector.hpp index 73a387dcd..41ab8c175 100644 --- a/include/boost/numeric/ublas/vector.hpp +++ b/include/boost/numeric/ublas/vector.hpp @@ -1691,8 +1691,8 @@ namespace boost { namespace numeric { namespace ublas { #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS using vector_container::operator (); #endif - typedef typename ALLOC::size_type size_type; - typedef typename ALLOC::difference_type difference_type; + typedef typename boost::allocator_size_type::type size_type; + typedef typename boost::allocator_difference_type::type difference_type; typedef T value_type; typedef const T &const_reference; typedef T &reference; @@ -1912,8 +1912,8 @@ namespace boost { namespace numeric { namespace ublas { #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS using vector_container::operator (); #endif - typedef typename ALLOC::size_type size_type; - typedef typename ALLOC::difference_type difference_type; + typedef typename boost::allocator_size_type::type size_type; + typedef typename boost::allocator_difference_type::type difference_type; typedef T value_type; typedef const T &const_reference; typedef T &reference; @@ -2175,8 +2175,8 @@ namespace boost { namespace numeric { namespace ublas { #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS using vector_container::operator (); #endif - typedef typename ALLOC::size_type size_type; - typedef typename ALLOC::difference_type difference_type; + typedef typename boost::allocator_size_type::type size_type; + typedef typename boost::allocator_difference_type::type difference_type; typedef T value_type; typedef const T &const_reference; typedef T &reference; diff --git a/test/Jamfile b/test/Jamfile index f1e100f94..f6716e2c6 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -252,5 +252,6 @@ test-suite numeric/uBLAS ] [ run test_matrix_vector.cpp ] + [ compile minimal_allocator_test.cpp ] ; diff --git a/test/minimal_allocator_test.cpp b/test/minimal_allocator_test.cpp new file mode 100644 index 000000000..d0ca531d1 --- /dev/null +++ b/test/minimal_allocator_test.cpp @@ -0,0 +1,51 @@ +/* +Copyright 2020 Glen Joseph Fernandes +(glenjofe@gmail.com) + +Distributed under the Boost Software License, Version 1.0. +(http://www.boost.org/LICENSE_1_0.txt) +*/ +#include +#if !defined(BOOST_NO_CXX11_ALLOCATOR) +#include +#include + +template +struct Allocator { + typedef T value_type; + + Allocator() BOOST_NOEXCEPT { } + + template + Allocator(const Allocator&) BOOST_NOEXCEPT { } + + T* allocate(std::size_t size) { + return static_cast(::operator new(sizeof(T) * size)); + } + + void deallocate(T* ptr, std::size_t) { + ::operator delete(ptr); + } +}; + +template +bool operator==(const Allocator&, const Allocator&) BOOST_NOEXCEPT +{ + return true; +} + +template +bool operator!=(const Allocator&, const Allocator&) BOOST_NOEXCEPT +{ + return false; +} + +int main() +{ + boost::numeric::ublas::matrix > > matrix(4, 4); + matrix(1, 2) = 3; +} +#endif