diff --git a/persistent-data/buffer.h b/persistent-data/buffer.h index 45e2390..d09e763 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 69ea853..de43f9e 100644 --- a/unit-tests/buffer_t.cc +++ b/unit-tests/buffer_t.cc @@ -82,6 +82,7 @@ BOOST_AUTO_TEST_CASE(buffer_8_a_8_access) 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; @@ -89,6 +90,7 @@ BOOST_AUTO_TEST_CASE(buffer_8_a_8_const_access) (*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) @@ -97,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)