From c200c0a9cacbed850f3cd76cddf9f1b21e678c22 Mon Sep 17 00:00:00 2001 From: Brian Johnson Date: Tue, 17 Apr 2018 09:48:39 -0500 Subject: [PATCH] Peer Review optimization requests. GH #2350 --- contracts/eosiolib/datastream.hpp | 26 ++++++++++++++++++-- libraries/fc/include/fc/io/raw.hpp | 33 +++++++++++++++++++------- libraries/fc/include/fc/io/raw_fwd.hpp | 10 ++++++-- 3 files changed, 56 insertions(+), 13 deletions(-) diff --git a/contracts/eosiolib/datastream.hpp b/contracts/eosiolib/datastream.hpp index 6d7c47add..3945891c1 100644 --- a/contracts/eosiolib/datastream.hpp +++ b/contracts/eosiolib/datastream.hpp @@ -254,16 +254,28 @@ DataStream& operator >> ( DataStream& ds, std::array& v ) { return ds; } -template +template::value == false || std::is_pointer::value == true, int> = 0> DataStream& operator << ( DataStream& ds, const T (&v)[N] ) { + static_assert(!std::is_pointer::value, "Pointers should not be serialized" ); ds << unsigned_int( N ); for( uint32_t i = 0; i < N; ++i ) ds << v[i]; return ds; } -template +template::value == true && std::is_pointer::value == false, int> = 0> +DataStream& operator << ( DataStream& ds, const T (&v)[N] ) { + ds << unsigned_int( N ); + ds.write((char*)&v[0], sizeof(v)); + return ds; +} + +template::value == false || std::is_pointer::value == true, int> = 0> DataStream& operator >> ( DataStream& ds, T (&v)[N] ) { + static_assert(!std::is_pointer::value, "Pointers should not be serialized" ); unsigned_int s; ds >> s; eosio_assert( N == s.value, "T[] size and unpacked size don't match"); @@ -272,6 +284,16 @@ DataStream& operator >> ( DataStream& ds, T (&v)[N] ) { return ds; } +template::value == true && std::is_pointer::value == false, int> = 0> +DataStream& operator >> ( DataStream& ds, T (&v)[N] ) { + unsigned_int s; + ds >> s; + eosio_assert( N == s.value, "T[] size and unpacked size don't match"); + ds.read((char*)&v[0], sizeof(v)); + return ds; +} + template DataStream& operator << ( DataStream& ds, const vector& v ) { ds << unsigned_int( v.size() ); diff --git a/libraries/fc/include/fc/io/raw.hpp b/libraries/fc/include/fc/io/raw.hpp index af6c51500..277192fee 100644 --- a/libraries/fc/include/fc/io/raw.hpp +++ b/libraries/fc/include/fc/io/raw.hpp @@ -140,12 +140,34 @@ namespace fc { usec = fc::microseconds(usec_as_int64); } FC_RETHROW_EXCEPTIONS( warn, "" ) } - template + template::value == false || std::is_pointer::value == true, int>> inline void pack( Stream& s, const fc::array& v) { for (uint64_t i = 0; i < N; ++i) fc::raw::pack(s, v.data[i]); } + template::value == true && std::is_pointer::value == false, int>> + inline void pack( Stream& s, const fc::array& v) { + s.write((const char*)&v.data[0], N*sizeof(T)); + } + + template::value == false || std::is_pointer::value == true, int>> + inline void unpack( Stream& s, fc::array& v) + { try { + for (uint64_t i = 0; i < N; ++i) + fc::raw::unpack(s, v.data[i]); + } FC_RETHROW_EXCEPTIONS( warn, "fc::array<${type},${length}>", ("type",fc::get_typename::name())("length",N) ) } + + template::value == true && std::is_pointer::value == false, int>> + inline void unpack( Stream& s, fc::array& v) + { try { + s.read((char*)&v.data[0], N*sizeof(T)); + } FC_RETHROW_EXCEPTIONS( warn, "fc::array<${type},${length}>", ("type",fc::get_typename::name())("length",N) ) } + template inline void pack( Stream& s, T (&v)[N]) { fc::raw::pack( s, unsigned_int((uint32_t)N) ); @@ -160,7 +182,7 @@ namespace fc { FC_ASSERT( size.value == N ); for (uint64_t i = 0; i < N; ++i) fc::raw::unpack(s, v[i]); - } FC_RETHROW_EXCEPTIONS( warn, "fc::array", ("type",fc::get_typename::name())("length",N) ) } + } FC_RETHROW_EXCEPTIONS( warn, "${type} (&v)[${length}]", ("type",fc::get_typename::name())("length",N) ) } template inline void pack( Stream& s, const std::shared_ptr& v) @@ -168,13 +190,6 @@ namespace fc { fc::raw::pack( s, *v ); } - template - inline void unpack( Stream& s, fc::array& v) - { try { - for (uint64_t i = 0; i < N; ++i) - fc::raw::unpack(s, v.data[i]); - } FC_RETHROW_EXCEPTIONS( warn, "fc::array", ("type",fc::get_typename::name())("length",N) ) } - template inline void unpack( Stream& s, std::shared_ptr& v) { try { diff --git a/libraries/fc/include/fc/io/raw_fwd.hpp b/libraries/fc/include/fc/io/raw_fwd.hpp index f397202fb..fa0aa72d9 100644 --- a/libraries/fc/include/fc/io/raw_fwd.hpp +++ b/libraries/fc/include/fc/io/raw_fwd.hpp @@ -111,8 +111,14 @@ namespace fc { template inline void pack( Stream& s, const std::vector& value ); template inline void unpack( Stream& s, std::vector& value ); - template inline void pack( Stream& s, const fc::array& v); - template inline void unpack( Stream& s, fc::array& v); + template::value == false || std::is_pointer::value == true, int> = 0> inline void pack( Stream& s, const fc::array& v); + template::value == true && std::is_pointer::value == false, int> = 0> inline void pack( Stream& s, const fc::array& v); + template::value == false || std::is_pointer::value == true, int> = 0> inline void unpack( Stream& s, fc::array& v); + template::value == true && std::is_pointer::value == false, int> = 0> inline void unpack( Stream& s, fc::array& v); template inline void pack( Stream& s, const bool& v ); template inline void unpack( Stream& s, bool& v ); -- GitLab