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