From 7e077993da05398c859f689ff3c0ce39656fa220 Mon Sep 17 00:00:00 2001 From: Andrey Semashev Date: Sat, 6 Aug 2016 17:02:28 +0300 Subject: [PATCH] Make better use of NRVO on compilers that support it. --- .../boost/log/attributes/scoped_attribute.hpp | 4 ++-- include/boost/log/core/record.hpp | 2 +- include/boost/log/core/record_view.hpp | 9 +++++---- include/boost/log/detail/config.hpp | 8 ++++++++ include/boost/log/detail/format.hpp | 2 +- .../expressions/formatters/char_decorator.hpp | 4 ++-- .../log/expressions/formatters/date_time.hpp | 4 ++-- .../log/expressions/formatters/named_scope.hpp | 4 ++-- .../expressions/formatters/wrap_formatter.hpp | 4 ++-- src/core.cpp | 16 +++++++++------- src/format_parser.cpp | 2 +- src/posix/object_name.cpp | 2 +- src/setup/settings_parser.cpp | 2 +- src/windows/object_name.cpp | 2 +- 14 files changed, 38 insertions(+), 27 deletions(-) diff --git a/include/boost/log/attributes/scoped_attribute.hpp b/include/boost/log/attributes/scoped_attribute.hpp index bd0e52d..6fbe788 100644 --- a/include/boost/log/attributes/scoped_attribute.hpp +++ b/include/boost/log/attributes/scoped_attribute.hpp @@ -128,7 +128,7 @@ BOOST_FORCEINLINE aux::scoped_logger_attribute< LoggerT > add_scoped_logger_attr return aux::scoped_logger_attribute< LoggerT >(l, name, attr); #else aux::scoped_logger_attribute< LoggerT > guard(l, name, attr); - return boost::move(guard); + return BOOST_LOG_NRVO_RESULT(guard); #endif } @@ -221,7 +221,7 @@ BOOST_FORCEINLINE aux::scoped_thread_attribute add_scoped_thread_attribute(attri return aux::scoped_thread_attribute(name, attr); #else aux::scoped_thread_attribute guard(name, attr); - return boost::move(guard); + return BOOST_LOG_NRVO_RESULT(guard); #endif } diff --git a/include/boost/log/core/record.hpp b/include/boost/log/core/record.hpp index b58177c..4210655 100644 --- a/include/boost/log/core/record.hpp +++ b/include/boost/log/core/record.hpp @@ -63,7 +63,7 @@ public: * * \post !*this == true */ - record() : m_impl(NULL) {} + BOOST_CONSTEXPR record() BOOST_NOEXCEPT : m_impl(NULL) {} /*! * Move constructor. Source record contents unspecified after the operation. diff --git a/include/boost/log/core/record_view.hpp b/include/boost/log/core/record_view.hpp index 6fa7a63..724bd01 100644 --- a/include/boost/log/core/record_view.hpp +++ b/include/boost/log/core/record_view.hpp @@ -17,6 +17,7 @@ #include #include +#include #include #include #include @@ -72,10 +73,10 @@ private: //! Attribute values view attribute_value_set m_attribute_values; - //! Constructor from the attribute sets - explicit public_data(BOOST_RV_REF(attribute_value_set) values) : + //! Constructor from the attribute value set + explicit public_data(BOOST_RV_REF(attribute_value_set) values) BOOST_NOEXCEPT : m_ref_counter(1), - m_attribute_values(values) + m_attribute_values(boost::move(values)) { } @@ -108,7 +109,7 @@ public: * * \post !*this == true */ - BOOST_DEFAULTED_FUNCTION(record_view(), {}) + BOOST_CONSTEXPR record_view() BOOST_NOEXCEPT {} /*! * Copy constructor diff --git a/include/boost/log/detail/config.hpp b/include/boost/log/detail/config.hpp index ce9aeb2..6005dd4 100644 --- a/include/boost/log/detail/config.hpp +++ b/include/boost/log/detail/config.hpp @@ -168,6 +168,14 @@ # define BOOST_LOG_UNREACHABLE_RETURN(r) BOOST_LOG_UNREACHABLE() #endif +// The macro efficiently returns a local lvalue from a function. +// It employs NRVO, if supported by compiler, or uses a move constructor otherwise. +#if defined(BOOST_HAS_NRVO) +#define BOOST_LOG_NRVO_RESULT(x) x +#else +#define BOOST_LOG_NRVO_RESULT(x) boost::move(x) +#endif + // Some compilers support a special attribute that shows that a function won't return #if defined(__GNUC__) || (defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x590) // GCC and Sun Studio 12 support attribute syntax diff --git a/include/boost/log/detail/format.hpp b/include/boost/log/detail/format.hpp index 89c6a9f..7f65df1 100644 --- a/include/boost/log/detail/format.hpp +++ b/include/boost/log/detail/format.hpp @@ -218,7 +218,7 @@ public: { string_type result; compose(result); - return boost::move(result); + return BOOST_LOG_NRVO_RESULT(result); } private: diff --git a/include/boost/log/expressions/formatters/char_decorator.hpp b/include/boost/log/expressions/formatters/char_decorator.hpp index 5f734b8..d053673 100644 --- a/include/boost/log/expressions/formatters/char_decorator.hpp +++ b/include/boost/log/expressions/formatters/char_decorator.hpp @@ -439,7 +439,7 @@ public: strm.flush(); m_impl(*strm.rdbuf()->storage()); - return boost::move(str); + return BOOST_LOG_NRVO_RESULT(str); } /*! @@ -471,7 +471,7 @@ public: strm.flush(); m_impl(*strm.rdbuf()->storage()); - return boost::move(str); + return BOOST_LOG_NRVO_RESULT(str); } BOOST_DELETED_FUNCTION(char_decorator_terminal()) diff --git a/include/boost/log/expressions/formatters/date_time.hpp b/include/boost/log/expressions/formatters/date_time.hpp index 45091fc..72029f0 100644 --- a/include/boost/log/expressions/formatters/date_time.hpp +++ b/include/boost/log/expressions/formatters/date_time.hpp @@ -126,7 +126,7 @@ public: stream_type strm(str); m_visitor_invoker(m_name, fusion::at_c< 0 >(phoenix::env(ctx).args()), binder1st< formatter_function_type&, stream_type& >(m_formatter, strm)); strm.flush(); - return boost::move(str); + return BOOST_LOG_NRVO_RESULT(str); } //! Invokation operator @@ -137,7 +137,7 @@ public: stream_type strm(str); m_visitor_invoker(m_name, fusion::at_c< 0 >(phoenix::env(ctx).args()), binder1st< formatter_function_type const&, stream_type& >(m_formatter, strm)); strm.flush(); - return boost::move(str); + return BOOST_LOG_NRVO_RESULT(str); } BOOST_DELETED_FUNCTION(format_date_time_terminal()) diff --git a/include/boost/log/expressions/formatters/named_scope.hpp b/include/boost/log/expressions/formatters/named_scope.hpp index cc45dc6..0f3b9c7 100644 --- a/include/boost/log/expressions/formatters/named_scope.hpp +++ b/include/boost/log/expressions/formatters/named_scope.hpp @@ -337,7 +337,7 @@ public: stream_type strm(str); m_visitor_invoker(m_name, fusion::at_c< 0 >(phoenix::env(ctx).args()), binder1st< formatter_function_type&, stream_type& >(m_formatter, strm)); strm.flush(); - return boost::move(str); + return BOOST_LOG_NRVO_RESULT(str); } //! Invokation operator @@ -348,7 +348,7 @@ public: stream_type strm(str); m_visitor_invoker(m_name, fusion::at_c< 0 >(phoenix::env(ctx).args()), binder1st< formatter_function_type const&, stream_type& >(m_formatter, strm)); strm.flush(); - return boost::move(str); + return BOOST_LOG_NRVO_RESULT(str); } BOOST_DELETED_FUNCTION(format_named_scope_terminal()) diff --git a/include/boost/log/expressions/formatters/wrap_formatter.hpp b/include/boost/log/expressions/formatters/wrap_formatter.hpp index 612be28..a5df456 100644 --- a/include/boost/log/expressions/formatters/wrap_formatter.hpp +++ b/include/boost/log/expressions/formatters/wrap_formatter.hpp @@ -199,7 +199,7 @@ public: stream_type strm(str); m_fun(fusion::at_c< 0 >(phoenix::env(ctx).args()), strm); strm.flush(); - return boost::move(str); + return BOOST_LOG_NRVO_RESULT(str); } //! Invokation operator @@ -210,7 +210,7 @@ public: stream_type strm(str); m_fun(fusion::at_c< 0 >(phoenix::env(ctx).args()), strm); strm.flush(); - return boost::move(str); + return BOOST_LOG_NRVO_RESULT(str); } }; diff --git a/src/core.cpp b/src/core.cpp index afec66e..b92c748 100644 --- a/src/core.cpp +++ b/src/core.cpp @@ -97,7 +97,7 @@ private: private: //! Initializing constructor - private_data(BOOST_RV_REF(attribute_value_set) values, uint32_t capacity) : + private_data(BOOST_RV_REF(attribute_value_set) values, uint32_t capacity) BOOST_NOEXCEPT : public_data(boost::move(values)), m_accepting_sink_count(0), m_accepting_sink_capacity(capacity), @@ -334,7 +334,9 @@ public: template< typename SourceAttributesT > BOOST_FORCEINLINE record open_record(BOOST_FWD_REF(SourceAttributesT) source_attributes) { - // Try a quick win first + record rec; + + // Try a quick win first if (m_enabled) try { thread_data* tsd = get_thread_data(); @@ -349,7 +351,6 @@ public: if (m_filter(attr_values)) { // The global filter passed, trying the sinks - record rec; attribute_value_set* values = &attr_values; if (!m_sinks.empty()) @@ -371,13 +372,12 @@ public: if (rec_impl && rec_impl->accepting_sink_count() == 0) { // No sinks accepted the record - return record(); + rec.reset(); + goto done; } // Some sinks have accepted the record values->freeze(); - - return boost::move(rec); } } } @@ -395,9 +395,11 @@ public: throw; m_exception_handler(); + rec.reset(); } - return record(); + done: + return BOOST_LOG_NRVO_RESULT(rec); } //! The method returns the current thread-specific data diff --git a/src/format_parser.cpp b/src/format_parser.cpp index 7afbda8..d797dd9 100644 --- a/src/format_parser.cpp +++ b/src/format_parser.cpp @@ -127,7 +127,7 @@ BOOST_LOG_API format_description< CharT > parse_format(const CharT* begin, const if (literal_start_pos < literal_chars_size) descr.format_elements.push_back(format_element::literal(literal_start_pos, literal_chars_size - literal_start_pos)); - return boost::move(descr); + return BOOST_LOG_NRVO_RESULT(descr); } diff --git a/src/posix/object_name.cpp b/src/posix/object_name.cpp index 0d2de72..9465fbb 100644 --- a/src/posix/object_name.cpp +++ b/src/posix/object_name.cpp @@ -117,7 +117,7 @@ std::string get_scope_prefix(object_name::scope ns) prefix.push_back('.'); - return boost::move(prefix); + return BOOST_LOG_NRVO_RESULT(prefix); } } // namespace diff --git a/src/setup/settings_parser.cpp b/src/setup/settings_parser.cpp index 5d8a927..8af2373 100644 --- a/src/setup/settings_parser.cpp +++ b/src/setup/settings_parser.cpp @@ -240,7 +240,7 @@ BOOST_LOG_SETUP_API basic_settings< CharT > parse_settings(std::basic_istream< C ++line_number; } - return boost::move(settings); + return BOOST_LOG_NRVO_RESULT(settings); } diff --git a/src/windows/object_name.cpp b/src/windows/object_name.cpp index f25ad64..b28848c 100644 --- a/src/windows/object_name.cpp +++ b/src/windows/object_name.cpp @@ -201,7 +201,7 @@ std::string get_scope_prefix(object_name::scope ns) prefix.push_back('.'); - return boost::move(prefix); + return BOOST_LOG_NRVO_RESULT(prefix); } } // namespace