README Container Design, Step 2 -------------------------------------------------------------------------------- From Step 1 we have a default constructor, a constructor creating a container with n default-initialized elements, and a destructor, which are all exception- safe (works properly in the presens of exceptions) and exception-neutral (propagates all exceptions to the caller, without causing any integrity problems in a Container object). Here we have added a copy constructor, move constructor, copy assignment operator, move assignment operator, and helper function allocate_and_copy_(). The "dangerous" stuff, is encapsulated in allocate_and_copy_(). allocate_and_copy_() -------------------- template T* Container:: allocate_and_copy_(const Container& c) { if (c.size() == 0) return nullptr; T* start = allocate_(c.size()); // can fail try { std::copy(c.start_, c.finish_, start); // can fail } catch (...) { deallocate_(start); // can't fail throw; } return start; } - allocate_() might throw, but is exception-safe and exception-neutral (Step 1). - std::copy() use T::operator=() to copy elements. If any of the assignments fail, copy will throw. The exception is then caught, and the memory referred to by new_start is deallocated. Deallocating the array will cause the destructor to be called for all elements in new_start, copied or not. - returning new_start, a pointer, cannot throw. Exception-safe and exception-neutral. Copy constructor and copy assigment operator -------------------------------------------- The only possible exception is from allocate_and_copy_(), both just propagates any exception, so, both are exception-safe and exception-neutral. Move constructor ---------------- Only pointer values involved, nothing can throw. Move assignment operator ------------------------ deallocate_() cannot throw, otherwise just pointer assignments, which cannot throw. Still fine, regarding robustness! --------------------------------------------------------------------------------