@@ -1636,6 +1636,7 @@ namespace po {
16361636 class parser {
16371637 using options_t = std::unordered_map< std::string, option >;
16381638 options_t m_options;
1639+ std::vector< options_t ::value_type* > m_order;
16391640 char const * m_program_name = " " ;
16401641 std::ostream* m_output_destination;
16411642
@@ -1942,10 +1943,14 @@ namespace po {
19421943 option& operator_brackets_helper ( std::string&& designator ) {
19431944 PROGRAMOPTIONS_ASSERT ( valid_designator ( designator ),
19441945 " operator[]: designator may only consist of letters, hyphens and underscores and mustn't start with a hyphen" );
1946+ // needed to provide strong exception safety
1947+ if ( m_order.capacity () == m_order.size () )
1948+ m_order.reserve ( m_order.size () + m_order.size () / 2 + 1 );
19451949 const bool empty = designator.empty ();
19461950 const char initial = designator.size () == 1 ? designator[ 0 ] : ' \0 ' ;
19471951 const auto result = m_options.emplace ( std::move ( designator ), option{} );
19481952 if ( result.second ) {
1953+ m_order.emplace_back ( &*result.first );
19491954 if ( initial )
19501955 result.first ->second .abbreviation ( initial );
19511956 if ( empty )
@@ -2000,7 +2005,8 @@ namespace po {
20002005 const std::size_t verbose_start = left_padding + abbreviation_width + separator_width;
20012006 const std::size_t verbose_width = std::min ( any_verbose * max_verbose_width, max_verbose );
20022007 const std::size_t description_start = verbose_start + verbose_width + mid_padding;
2003- for ( auto && opt : object.m_options ) {
2008+ for ( auto iter = object.m_order .begin (); iter != object.m_order .end (); ++iter ) {
2009+ auto & opt = **iter;
20042010 if ( opt.first .empty () )
20052011 continue ;
20062012 stream << repeat{ left_padding, ' ' };
0 commit comments