Skip to content

Commit 039d18c

Browse files
committed
Improve operator[] safety
1 parent 24783de commit 039d18c

File tree

1 file changed

+60
-55
lines changed

1 file changed

+60
-55
lines changed

include/tao/json/value.hh

Lines changed: 60 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -587,61 +587,6 @@ namespace tao
587587
}
588588
}
589589

590-
basic_value & operator[] ( const std::size_t index ) noexcept
591-
{
592-
return m_union.a[ index ];
593-
}
594-
595-
const basic_value & operator[] ( const std::size_t index ) const noexcept
596-
{
597-
return m_union.a[ index ];
598-
}
599-
600-
basic_value & operator[] ( const std::string & key )
601-
{
602-
return m_union.o[ key ];
603-
}
604-
605-
basic_value & operator[] ( std::string && key )
606-
{
607-
return m_union.o[ std::move( key ) ];
608-
}
609-
610-
basic_value & operator[] ( const pointer & k )
611-
{
612-
if ( ! k ) {
613-
return * this;
614-
}
615-
const auto b = k.begin();
616-
const auto e = std::prev( k.end() );
617-
basic_value & v = internal::pointer_at( this, b, e );
618-
switch ( v.m_type ) {
619-
case json::type::ARRAY:
620-
{
621-
if ( e->key() == "-" ) {
622-
v.unsafe_emplace_back( null );
623-
return v.m_union.a.back();
624-
}
625-
return v.at( e->index() );
626-
}
627-
break;
628-
case json::type::OBJECT:
629-
{
630-
const auto & k = e->key();
631-
const auto it = v.m_union.o.find( k );
632-
if ( it == v.m_union.o.end() ) {
633-
const auto r = v.unsafe_emplace( k, null );
634-
assert( r.second );
635-
return r.first->second;
636-
}
637-
return it->second;
638-
}
639-
break;
640-
default:
641-
throw internal::invalid_type( b, std::next( e ) );
642-
}
643-
}
644-
645590
template< typename T >
646591
tao::optional< T > optional( const std::string & key ) const
647592
{
@@ -870,6 +815,66 @@ namespace tao
870815
}
871816
}
872817

818+
819+
basic_value & operator[] ( const std::size_t index ) noexcept
820+
{
821+
assert( m_type == type::ARRAY );
822+
return m_union.a[ index ];
823+
}
824+
825+
const basic_value & operator[] ( const std::size_t index ) const noexcept
826+
{
827+
assert( m_type == type::ARRAY );
828+
return m_union.a[ index ];
829+
}
830+
831+
basic_value & operator[] ( const std::string & key )
832+
{
833+
prepare_object();
834+
return m_union.o[ key ];
835+
}
836+
837+
basic_value & operator[] ( std::string && key )
838+
{
839+
prepare_object();
840+
return m_union.o[ std::move( key ) ];
841+
}
842+
843+
basic_value & operator[] ( const pointer & k )
844+
{
845+
if ( ! k ) {
846+
return * this;
847+
}
848+
const auto b = k.begin();
849+
const auto e = std::prev( k.end() );
850+
basic_value & v = internal::pointer_at( this, b, e );
851+
switch ( v.m_type ) {
852+
case json::type::ARRAY:
853+
{
854+
if ( e->key() == "-" ) {
855+
v.unsafe_emplace_back( null );
856+
return v.m_union.a.back();
857+
}
858+
return v.at( e->index() );
859+
}
860+
break;
861+
case json::type::OBJECT:
862+
{
863+
const auto & k = e->key();
864+
const auto it = v.m_union.o.find( k );
865+
if ( it == v.m_union.o.end() ) {
866+
const auto r = v.unsafe_emplace( k, null );
867+
assert( r.second );
868+
return r.first->second;
869+
}
870+
return it->second;
871+
}
872+
break;
873+
default:
874+
throw internal::invalid_type( b, std::next( e ) );
875+
}
876+
}
877+
873878
bool empty() const noexcept
874879
{
875880
switch ( m_type ) {

0 commit comments

Comments
 (0)