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)) {
special = true;
stream << ".nan";
} else if (std::numeric_limits<T>::has_infinity) {
if (value == std::numeric_limits<T>::infinity()) {
special = true;
stream << ".inf";
} else if (value == -std::numeric_limits<T>::infinity()) {
special = true;
} else if (std::numeric_limits<T>::has_infinity && std::isinf(value)) {
special = true;
if (std::signbit(value)) {
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,
shared_memory_holder pMemory) {
if (key > sequence.size() || (key > 0 && !sequence[key - 1]->is_defined()))
return 0;
return nullptr;
if (key == sequence.size())
sequence.push_back(&pMemory->create_node());
return sequence[key];

View File

@@ -7,12 +7,18 @@
#pragma once
#endif
#include "yaml-cpp/noexcept.h"
#include <memory>
#include <utility>
#include <vector>
namespace YAML {
class SettingChangeBase;
class SettingChangeBase {
public:
virtual ~SettingChangeBase() = default;
virtual void pop() = 0;
};
template <typename T>
class Setting {
@@ -28,12 +34,6 @@ class Setting {
T m_value;
};
class SettingChangeBase {
public:
virtual ~SettingChangeBase() = default;
virtual void pop() = 0;
};
template <typename T>
class SettingChange : public SettingChangeBase {
public:
@@ -64,16 +64,25 @@ class SettingChanges {
public:
SettingChanges() : m_settingChanges{} {}
SettingChanges(const SettingChanges&) = delete;
SettingChanges(SettingChanges&&) = default;
SettingChanges(SettingChanges&&) YAML_CPP_NOEXCEPT = default;
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(); }
void clear() {
void clear() YAML_CPP_NOEXCEPT {
restore();
m_settingChanges.clear();
}
void restore() {
void restore() YAML_CPP_NOEXCEPT {
for (setting_changes::const_iterator it = m_settingChanges.begin();
it != m_settingChanges.end(); ++it)
(*it)->pop();
@@ -83,19 +92,8 @@ class SettingChanges {
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:
using setting_changes = std::vector<std::unique_ptr<SettingChangeBase> >;
using setting_changes = std::vector<std::unique_ptr<SettingChangeBase>>;
setting_changes m_settingChanges;
};
} // 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,
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));
return static_cast<char>(
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
// the YAML specification for the determination algorithm.
char_traits::int_type intro[4];
char_traits::int_type intro[4]{};
int nIntroUsed = 0;
UtfIntroState state = uis_start;
for (; !s_introFinalState[state];) {
@@ -273,9 +273,11 @@ char Stream::get() {
// . Extracts 'n' characters from the stream and updates our position
std::string Stream::get(int n) {
std::string ret;
ret.reserve(n);
for (int i = 0; i < n; i++)
ret += get();
if(n > 0) {
ret.reserve(static_cast<std::string::size_type>(n));
for (int i = 0; i < n; i++)
ret += get();
}
return ret;
}
@@ -326,7 +328,7 @@ bool Stream::_ReadAheadTo(size_t i) const {
void Stream::StreamInUtf8() const {
unsigned char b = GetNextByte();
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>
namespace YAML {
class StreamCharSource;
class Stream {
public:
friend class StreamCharSource;

View File

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