Make SettingChange and StreamCharSourcemove constructors and assignment operators noexcept (#808)

The explicitly defaulted or implemented move constructors and assignment
operators are made "noexcept".

Bugfix:
* src/stream.cpp Stream::Stream() char_traits::int_type intro[4] is
  now aggregate-initialized (to zero) to avoid UB.

Minor changes:
* Using std::isinf() and std::signbit() instead of comparing for
  equality with infinity.
* src/streamcharsource.h: Added #include "stream.h".
* src/stream.h: Forward declaring "class StreamCharSource".
* Some implicit casting changed into static_cast's.

Signed-off-by: Ted Lyngmo <ted@lyncon.se>
This commit is contained in:
Ted Lyngmo
2020-02-04 23:58:00 +01:00
committed by GitHub
parent 1928bca4a4
commit 9ab22ef493
6 changed files with 42 additions and 37 deletions

View File

@@ -164,13 +164,12 @@ inline Emitter& Emitter::WriteStreamable(T value) {
std::isnan(value)) { std::isnan(value)) {
special = true; special = true;
stream << ".nan"; stream << ".nan";
} else if (std::numeric_limits<T>::has_infinity) { } else if (std::numeric_limits<T>::has_infinity && std::isinf(value)) {
if (value == std::numeric_limits<T>::infinity()) { special = true;
special = true; if (std::signbit(value)) {
stream << ".inf";
} else if (value == -std::numeric_limits<T>::infinity()) {
special = true;
stream << "-.inf"; stream << "-.inf";
} else {
stream << ".inf";
} }
} }
} }

View File

@@ -33,7 +33,7 @@ struct get_idx<Key,
static node* get(std::vector<node*>& sequence, const Key& key, static node* get(std::vector<node*>& sequence, const Key& key,
shared_memory_holder pMemory) { shared_memory_holder pMemory) {
if (key > sequence.size() || (key > 0 && !sequence[key - 1]->is_defined())) if (key > sequence.size() || (key > 0 && !sequence[key - 1]->is_defined()))
return 0; return nullptr;
if (key == sequence.size()) if (key == sequence.size())
sequence.push_back(&pMemory->create_node()); sequence.push_back(&pMemory->create_node());
return sequence[key]; return sequence[key];

View File

@@ -7,12 +7,18 @@
#pragma once #pragma once
#endif #endif
#include "yaml-cpp/noexcept.h"
#include <memory> #include <memory>
#include <utility> #include <utility>
#include <vector> #include <vector>
namespace YAML { namespace YAML {
class SettingChangeBase;
class SettingChangeBase {
public:
virtual ~SettingChangeBase() = default;
virtual void pop() = 0;
};
template <typename T> template <typename T>
class Setting { class Setting {
@@ -28,12 +34,6 @@ class Setting {
T m_value; T m_value;
}; };
class SettingChangeBase {
public:
virtual ~SettingChangeBase() = default;
virtual void pop() = 0;
};
template <typename T> template <typename T>
class SettingChange : public SettingChangeBase { class SettingChange : public SettingChangeBase {
public: public:
@@ -64,16 +64,25 @@ class SettingChanges {
public: public:
SettingChanges() : m_settingChanges{} {} SettingChanges() : m_settingChanges{} {}
SettingChanges(const SettingChanges&) = delete; SettingChanges(const SettingChanges&) = delete;
SettingChanges(SettingChanges&&) = default; SettingChanges(SettingChanges&&) YAML_CPP_NOEXCEPT = default;
SettingChanges& operator=(const SettingChanges&) = delete; SettingChanges& operator=(const SettingChanges&) = delete;
SettingChanges& operator=(SettingChanges&& rhs) YAML_CPP_NOEXCEPT {
if (this == &rhs)
return *this;
clear();
std::swap(m_settingChanges, rhs.m_settingChanges);
return *this;
}
~SettingChanges() { clear(); } ~SettingChanges() { clear(); }
void clear() { void clear() YAML_CPP_NOEXCEPT {
restore(); restore();
m_settingChanges.clear(); m_settingChanges.clear();
} }
void restore() { void restore() YAML_CPP_NOEXCEPT {
for (setting_changes::const_iterator it = m_settingChanges.begin(); for (setting_changes::const_iterator it = m_settingChanges.begin();
it != m_settingChanges.end(); ++it) it != m_settingChanges.end(); ++it)
(*it)->pop(); (*it)->pop();
@@ -83,19 +92,8 @@ class SettingChanges {
m_settingChanges.push_back(std::move(pSettingChange)); m_settingChanges.push_back(std::move(pSettingChange));
} }
// like std::unique_ptr - assignment is transfer of ownership
SettingChanges& operator=(SettingChanges&& rhs) {
if (this == &rhs)
return *this;
clear();
std::swap(m_settingChanges, rhs.m_settingChanges);
return *this;
}
private: private:
using setting_changes = std::vector<std::unique_ptr<SettingChangeBase> >; using setting_changes = std::vector<std::unique_ptr<SettingChangeBase>>;
setting_changes m_settingChanges; setting_changes m_settingChanges;
}; };
} // namespace YAML } // namespace YAML

View File

@@ -151,7 +151,7 @@ inline UtfIntroCharType IntroCharTypeOf(std::istream::int_type ch) {
inline char Utf8Adjust(unsigned long ch, unsigned char lead_bits, inline char Utf8Adjust(unsigned long ch, unsigned char lead_bits,
unsigned char rshift) { unsigned char rshift) {
const unsigned char header = ((1 << lead_bits) - 1) << (8 - lead_bits); const unsigned char header = static_cast<unsigned char>(((1 << lead_bits) - 1) << (8 - lead_bits));
const unsigned char mask = (0xFF >> (lead_bits + 1)); const unsigned char mask = (0xFF >> (lead_bits + 1));
return static_cast<char>( return static_cast<char>(
static_cast<unsigned char>(header | ((ch >> rshift) & mask))); static_cast<unsigned char>(header | ((ch >> rshift) & mask)));
@@ -196,7 +196,7 @@ Stream::Stream(std::istream& input)
// Determine (or guess) the character-set by reading the BOM, if any. See // Determine (or guess) the character-set by reading the BOM, if any. See
// the YAML specification for the determination algorithm. // the YAML specification for the determination algorithm.
char_traits::int_type intro[4]; char_traits::int_type intro[4]{};
int nIntroUsed = 0; int nIntroUsed = 0;
UtfIntroState state = uis_start; UtfIntroState state = uis_start;
for (; !s_introFinalState[state];) { for (; !s_introFinalState[state];) {
@@ -273,9 +273,11 @@ char Stream::get() {
// . Extracts 'n' characters from the stream and updates our position // . Extracts 'n' characters from the stream and updates our position
std::string Stream::get(int n) { std::string Stream::get(int n) {
std::string ret; std::string ret;
ret.reserve(n); if(n > 0) {
for (int i = 0; i < n; i++) ret.reserve(static_cast<std::string::size_type>(n));
ret += get(); for (int i = 0; i < n; i++)
ret += get();
}
return ret; return ret;
} }
@@ -326,7 +328,7 @@ bool Stream::_ReadAheadTo(size_t i) const {
void Stream::StreamInUtf8() const { void Stream::StreamInUtf8() const {
unsigned char b = GetNextByte(); unsigned char b = GetNextByte();
if (m_input.good()) { if (m_input.good()) {
m_readahead.push_back(b); m_readahead.push_back(static_cast<char>(b));
} }
} }

View File

@@ -16,6 +16,9 @@
#include <string> #include <string>
namespace YAML { namespace YAML {
class StreamCharSource;
class Stream { class Stream {
public: public:
friend class StreamCharSource; friend class StreamCharSource;

View File

@@ -7,14 +7,17 @@
#pragma once #pragma once
#endif #endif
#include "yaml-cpp/noexcept.h"
#include "stream.h"
#include <cstddef> #include <cstddef>
namespace YAML { namespace YAML {
class StreamCharSource { class StreamCharSource {
public: public:
StreamCharSource(const Stream& stream) : m_offset(0), m_stream(stream) {} StreamCharSource(const Stream& stream) : m_offset(0), m_stream(stream) {}
StreamCharSource(const StreamCharSource& source) = default; StreamCharSource(const StreamCharSource& source) = default;
StreamCharSource(StreamCharSource&&) = default; StreamCharSource(StreamCharSource&&) YAML_CPP_NOEXCEPT = default;
StreamCharSource& operator=(const StreamCharSource&) = delete; StreamCharSource& operator=(const StreamCharSource&) = delete;
StreamCharSource& operator=(StreamCharSource&&) = delete; StreamCharSource& operator=(StreamCharSource&&) = delete;
~StreamCharSource() = default; ~StreamCharSource() = default;
@@ -37,7 +40,7 @@ inline StreamCharSource::operator bool() const {
inline const StreamCharSource StreamCharSource::operator+(int i) const { inline const StreamCharSource StreamCharSource::operator+(int i) const {
StreamCharSource source(*this); StreamCharSource source(*this);
if (static_cast<int>(source.m_offset) + i >= 0) if (static_cast<int>(source.m_offset) + i >= 0)
source.m_offset += i; source.m_offset += static_cast<std::size_t>(i);
else else
source.m_offset = 0; source.m_offset = 0;
return source; return source;