Introduce a new _M_compile function which does the common work needed by all constructors and assignment. Call that directly to avoid multiple levels of constructor delegation or calls to basic_regex::assign overloads. For assignment, there is no need to construct a std::basic_string if we already have a contiguous sequence of the correct character type, and no need to construct a temporary basic_regex when assigning from an existing basic_regex. Also define the copy and move assignment operators as defaulted, which does the right thing without constructing a temporary and swapping it. Copying or moving the shared_ptr member cannot fail, so they can be noexcept. The assign(const basic_regex&) and assign(basic_regex&&) member can then be defined in terms of copy or move assignment. The new _M_compile function takes pointer arguments, so the caller has to convert arbitrary iterator ranges into a contiguous sequence of characters. With that simplification, the __compile_nfa helpers are not needed and can be removed. This also fixes a bug where construction from a contiguous sequence with the wrong character type would fail to compile, rather than converting the elements to the regex character type. Signed-off-by: Jonathan Wakely libstdc++-v3/ChangeLog: * include/bits/regex.h (__detail::__is_contiguous_iter): Move here from . (basic_regex::_M_compile): New function to compile an NFA from a regular expression string. (basic_regex::basic_regex): Use _M_compile instead of delegating to other constructors. (basic_regex::operator=(const basic_regex&)): Define as defaulted. (basic_regex::operator=(initializer_list)): Use _M_compile. (basic_regex::assign(const basic_regex&)): Use copy assignment. (basic_regex::assign(basic_regex&&)): Use move assignment. (basic_regex::assign(const C*, flag_type)): Use _M_compile instead of constructing a temporary string. (basic_regex::assign(const C*, size_t, flag_type)): Likewise. (basic_regex::assign(const basic_string&, flag_type)): Use _M_compile instead of constructing a temporary basic_regex. (basic_regex::assign(InputIter, InputIter, flag_type)): Avoid constructing a temporary string for contiguous iterators of the right value type. * include/bits/regex_compiler.h (__is_contiguous_iter): Move to . (__enable_if_contiguous_iter, __disable_if_contiguous_iter) (__compile_nfa): Remove. * testsuite/28_regex/basic_regex/assign/exception_safety.cc: New test. * testsuite/28_regex/basic_regex/ctors/char/other.cc: New test. Tested x86_64-linux. Committed to trunk.