diff --git a/persistent-data/buffer.h b/persistent-data/buffer.h index 45e2390..051db59 100644 --- a/persistent-data/buffer.h +++ b/persistent-data/buffer.h @@ -26,6 +26,7 @@ #include #include #include +#include #include @@ -43,6 +44,9 @@ namespace persistent_data { template class buffer : private boost::noncopyable { public: + BOOST_STATIC_ASSERT_MSG((Alignment > 1) & !(Alignment & (Alignment - 1)), + "Alignment must be a power of two."); + typedef boost::shared_ptr ptr; typedef boost::shared_ptr const_ptr; @@ -73,7 +77,11 @@ namespace persistent_data { // Allocates size bytes and returns a pointer to the // allocated memory. The memory address will be a // multiple of 'Alignment', which must be a power of two - return memalign(Alignment, s); + void *mem = memalign(Alignment, s); + if (!mem) + throw std::bad_alloc(); + + return mem; } static void operator delete(void *p) { diff --git a/unit-tests/buffer_t.cc b/unit-tests/buffer_t.cc index a5d98a5..382b4da 100644 --- a/unit-tests/buffer_t.cc +++ b/unit-tests/buffer_t.cc @@ -79,24 +79,18 @@ BOOST_AUTO_TEST_CASE(buffer_8_a_8_access) buffer::ptr b = create_buffer(); (*b)[0] = 0; - BOOST_CHECK_EQUAL((*b)[0], '\0'); -} - -BOOST_AUTO_TEST_CASE(buffer_8_a_8_oob) -{ - uint32_t const sz = 8, align = 8; - buffer::ptr b = create_buffer(); - - BOOST_CHECK_NO_THROW((*b)[8] = 0); + BOOST_CHECK_EQUAL((*b)[0], 0); } +#if 0 BOOST_AUTO_TEST_CASE(buffer_8_a_8_const_access) { uint32_t const sz = 8, align = 8; buffer::const_ptr b = create_buffer(); - // (*b)[0] = 0; // Compile time error accessing read-only location + (*b)[0] = 0; // Compile time error accessing read-only location } +#endif // 8 byte buffer size, varying alignment from 1 - 7 BOOST_AUTO_TEST_CASE(buffer_128_a_1_fails) @@ -105,6 +99,7 @@ BOOST_AUTO_TEST_CASE(buffer_128_a_1_fails) buffer::ptr b = create_buffer(); BOOST_CHECK(!b); + BOOST_CHECK_EQUAL((unsigned long) b->raw() & (align - 1), 1); } BOOST_AUTO_TEST_CASE(buffer_128_a_2_succeeds)