mirror of
https://github.com/jbeder/yaml-cpp.git
synced 2025-09-09 12:41:17 +00:00
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:
@@ -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";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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];
|
||||||
|
@@ -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
|
||||||
|
@@ -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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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;
|
||||||
|
@@ -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;
|
||||||
|
Reference in New Issue
Block a user