Boost logo

Boost :

From: Robert Ramey (ramey_at_[hidden])
Date: 2003-12-05 16:43:56


David Abrahams wrote:

http://lists.boost.org/MailArchives/boost/msg53875.php

in response the above I crafted the following functions to allocate space
for a type from the heap without invoking a constructor. The intention
is to use the correct new - either a specific class overload one if
it exists or a the global one if it doesn't.

I get errors on the two compilers I used. GCC 3.2 under cygwin
just crashes with:

c:/boost-dev/libs/serialization/test/test_zmisc.cpp: In instantiation of `heap_allocator<A>':
c:/boost-dev/libs/serialization/test/test_zmisc.cpp:48: instantiated from here
c:/boost-dev/libs/serialization/test/test_zmisc.cpp:21: internal error:
   Segmentation fault
Please submit a full bug report,
with preprocessed source if appropriate.
See <URL:http://www.gnu.org/software/gcc/bugs.html> for instructions.

while VC 7.0 gives me:
c:\boost-dev\libs\serialization\test\test_zmisc.cpp(21) : error C2275: 'new' : illegal use of this type as an expression
        c:\boost-dev\libs\serialization\test\test_zmisc.cpp(48) : see reference to class template instantiation 'heap_allocator<T>' being compiled
        with
        [
            T=A
        ]
c:\boost-dev\libs\serialization\test\test_zmisc.cpp(21) : error C2955: 'heap_allocator<T>::test' : use of class template requires template argument list
        with
        [
            T=A
        ]
        c:\boost-dev\libs\serialization\test\test_zmisc.cpp(17) : see declaration of 'heap_allocator<T>::test'
        with
        [
            T=A
        ]
...

Could you help me out with this?

Robert Ramey

#include <new>

// note trick to be sure that operator new is using class specific
// version if such exists. Due to Peter Dimov.
// note: the following fails if T has no default constructor.
// otherwise it would have been ideal
//struct heap_allocator : public T
//{
// T * invoke(){
// return ::new(sizeof(T));
// }
//}

template<class T>
struct heap_allocator
{
        template <class U, U x> struct test;
        typedef char* yes;
        typedef int* no;
        template <class U>
        yes has_op_new(U*, test<void* (*)(std::size_t), & U::operator new> * = 0);
        no has_op_new(...);

        template<class U>
        T * new_operator(U);

        T * new_operator(yes){
                return (T::operator new)(sizeof(T));
        }
        T * new_operator(no){
                return static_cast<T *>(operator new(sizeof(T)));
        }
        static T * invoke(){
                return new_operator(has_op_new(static_cast<T *>(NULL)));
        }
};

class A {
};

class B {
public:
        void * operator new(size_t s);
};

int
main(int argc, char *argv[]){
    A * a = heap_allocator<A>::invoke(); // never throws ?
    B * b = heap_allocator<B>::invoke(); // never throws ?
}


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk