Skip to content

Commit

Permalink
fix: ensure forwarding constructors have constraints (#290)
Browse files Browse the repository at this point in the history
* fix: ensure forwarding constructors have constraints that prevent copying / moving objects of the same type

* Update infra/stream/InputStream.hpp

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* Resolve SonarCloud violations as a result of applying SonalCloud recommendations

* infra/stream/InputStream: Remove duplication by extracting InputStreamWithReader and InputStreamWithErrorPolicy

* infra/stream/OutputStream: Remove duplication by extracting OutputStreamWithReader and OutputStreamWithErrorPolicy

* Rename TheReader/TheWriter to ReaderType/WriterType

* InputStreamWithErrorPolicy, OutputStreamWithErrorPolicy: Delete assignment operators

* infra/stream/InputStream, Outputstream: Disable warnings "Remove this class' copy constructor so that the class follows the rule of Zero"

* infra/stream/InputStream, Outputstream: Disable warnings "Remove this class' copy constructor so that the class follows the rule of Zero"

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
  • Loading branch information
richardapeters and github-actions[bot] committed May 22, 2023
1 parent 77eb417 commit 5015938
Show file tree
Hide file tree
Showing 8 changed files with 226 additions and 332 deletions.
38 changes: 0 additions & 38 deletions infra/stream/InputStream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -411,44 +411,6 @@ namespace infra
}
}

DataInputStream::WithErrorPolicy::WithErrorPolicy(StreamReader& reader)
: DataInputStream(reader, errorPolicy)
{}

DataInputStream::WithErrorPolicy::WithErrorPolicy(StreamReader& reader, SoftFail)
: DataInputStream(reader, errorPolicy)
, errorPolicy(softFail)
{}

DataInputStream::WithErrorPolicy::WithErrorPolicy(StreamReader& reader, NoFail)
: DataInputStream(reader, errorPolicy)
, errorPolicy(noFail)
{}

DataInputStream::WithErrorPolicy::WithErrorPolicy(const WithErrorPolicy& other)
: DataInputStream(other.Reader(), errorPolicy)
, errorPolicy(other.ErrorPolicy())
{}

TextInputStream::WithErrorPolicy::WithErrorPolicy(StreamReader& reader)
: TextInputStream(reader, errorPolicy)
{}

TextInputStream::WithErrorPolicy::WithErrorPolicy(StreamReader& reader, SoftFail)
: TextInputStream(reader, errorPolicy)
, errorPolicy(softFail)
{}

TextInputStream::WithErrorPolicy::WithErrorPolicy(StreamReader& reader, NoFail)
: TextInputStream(reader, errorPolicy)
, errorPolicy(noFail)
{}

TextInputStream::WithErrorPolicy::WithErrorPolicy(const WithErrorPolicy& other)
: TextInputStream(other.Reader(), errorPolicy)
, errorPolicy(other.ErrorPolicy())
{}

namespace
{
uint8_t DecodeHexByte(char hex)
Expand Down
208 changes: 88 additions & 120 deletions infra/stream/InputStream.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,13 +63,54 @@ namespace infra
StreamErrorPolicy& errorPolicy;
};

template<class Parent, class ReaderType>
class InputStreamWithReader //NOSONAR
: private detail::StorageHolder<ReaderType, InputStreamWithReader<Parent, ReaderType>>
, public Parent
{
public:
InputStreamWithReader();
template<class Arg>
explicit InputStreamWithReader(Arg&& arg, std::enable_if_t<!std::is_same_v<InputStreamWithReader, std::remove_cv_t<std::remove_reference_t<Arg>>>, std::nullptr_t> = nullptr);
template<class Arg0, class Arg1, class... Args>
explicit InputStreamWithReader(Arg0&& arg0, Arg1&& arg1, Args&&... args);
template<class Storage, class... Args>
InputStreamWithReader(Storage&& storage, const SoftFail&, Args&&... args);
template<class Storage, class... Args>
InputStreamWithReader(Storage&& storage, const NoFail&, Args&&... args);
InputStreamWithReader(const InputStreamWithReader& other);
InputStreamWithReader& operator=(const InputStreamWithReader& other) = delete;
~InputStreamWithReader() = default;

ReaderType& Reader();

private:
StreamErrorPolicy errorPolicy;
};

template<class Parent>
class InputStreamWithErrorPolicy //NOSONAR
: public Parent
{
public:
explicit InputStreamWithErrorPolicy(StreamReader& reader);
InputStreamWithErrorPolicy(StreamReader& reader, SoftFail);
InputStreamWithErrorPolicy(StreamReader& reader, NoFail);
InputStreamWithErrorPolicy(const InputStreamWithErrorPolicy& other);
InputStreamWithErrorPolicy& operator=(const InputStreamWithErrorPolicy& other) = delete;
~InputStreamWithErrorPolicy() = default;

private:
StreamErrorPolicy errorPolicy;
};

class DataInputStream
: public InputStream
{
public:
template<class Reader>
class WithReader;
class WithErrorPolicy;
using WithReader = InputStreamWithReader<DataInputStream, Reader>;
using WithErrorPolicy = InputStreamWithErrorPolicy<DataInputStream>;

using InputStream::InputStream;

Expand All @@ -87,8 +128,8 @@ namespace infra
{
public:
template<class Reader>
class WithReader;
class WithErrorPolicy;
using WithReader = InputStreamWithReader<TextInputStream, Reader>;
using WithErrorPolicy = InputStreamWithErrorPolicy<TextInputStream>;

using InputStream::InputStream;

Expand Down Expand Up @@ -129,78 +170,6 @@ namespace infra
infra::Optional<std::size_t> width;
};

template<class TheReader>
class DataInputStream::WithReader
: private detail::StorageHolder<TheReader, WithReader<TheReader>>
, public DataInputStream
{
public:
template<class... Args>
explicit WithReader(Args&&... args);
template<class Storage, class... Args>
WithReader(Storage&& storage, const SoftFail&, Args&&... args);
template<class Storage, class... Args>
WithReader(Storage&& storage, const NoFail&, Args&&... args);
WithReader(const WithReader& other);
WithReader& operator=(const WithReader& other) = delete;
~WithReader() = default;

TheReader& Reader();

private:
StreamErrorPolicy errorPolicy;
};

class DataInputStream::WithErrorPolicy
: public DataInputStream
{
public:
explicit WithErrorPolicy(StreamReader& reader);
WithErrorPolicy(StreamReader& reader, SoftFail);
WithErrorPolicy(StreamReader& reader, NoFail);
WithErrorPolicy(const WithErrorPolicy& other);
~WithErrorPolicy() = default;

private:
StreamErrorPolicy errorPolicy;
};

template<class TheReader>
class TextInputStream::WithReader
: private detail::StorageHolder<TheReader, WithReader<TheReader>>
, public TextInputStream
{
public:
template<class... Args>
explicit WithReader(Args&&... args);
template<class Storage, class... Args>
WithReader(Storage&& storage, const SoftFail&, Args&&... args);
template<class Storage, class... Args>
WithReader(Storage&& storage, const NoFail&, Args&&... args);
WithReader(const WithReader& other);
WithReader& operator=(const WithReader& other) = delete;
~WithReader() = default;

TheReader& Reader();

private:
StreamErrorPolicy errorPolicy;
};

class TextInputStream::WithErrorPolicy
: public TextInputStream
{
public:
explicit WithErrorPolicy(StreamReader& writer);
WithErrorPolicy(StreamReader& writer, SoftFail);
WithErrorPolicy(StreamReader& writer, NoFail);
WithErrorPolicy(const WithErrorPolicy& other);
~WithErrorPolicy() = default;

private:
StreamErrorPolicy errorPolicy;
};

class FromHexHelper
{
public:
Expand Down Expand Up @@ -248,77 +217,76 @@ namespace infra
return result;
}

template<class TheReader>
template<class... Args>
DataInputStream::WithReader<TheReader>::WithReader(Args&&... args)
: detail::StorageHolder<TheReader, WithReader<TheReader>>(std::forward<Args>(args)...)
, DataInputStream(this->storage, errorPolicy)
template<class Parent, class ReaderType>
InputStreamWithReader<Parent, ReaderType>::InputStreamWithReader()
: Parent(this->storage, errorPolicy)
{}

template<class Parent, class ReaderType>
template<class Arg>
InputStreamWithReader<Parent, ReaderType>::InputStreamWithReader(Arg&& arg, std::enable_if_t<!std::is_same_v<InputStreamWithReader, std::remove_cv_t<std::remove_reference_t<Arg>>>, std::nullptr_t>)
: detail::StorageHolder<ReaderType, InputStreamWithReader<Parent, ReaderType>>(std::forward<Arg>(arg))
, Parent(this->storage, errorPolicy)
{}

template<class TheReader>
template<class Parent, class ReaderType>
template<class Arg0, class Arg1, class... Args>
InputStreamWithReader<Parent, ReaderType>::InputStreamWithReader(Arg0&& arg0, Arg1&& arg1, Args&&... args)
: detail::StorageHolder<ReaderType, InputStreamWithReader<Parent, ReaderType>>(std::forward<Arg0>(arg0), std::forward<Arg1>(arg1), std::forward<Args>(args)...)
, Parent(this->storage, errorPolicy)
{}

template<class Parent, class ReaderType>
template<class Storage, class... Args>
DataInputStream::WithReader<TheReader>::WithReader(Storage&& storage, const SoftFail&, Args&&... args)
: detail::StorageHolder<TheReader, WithReader<TheReader>>(std::forward<Storage>(storage), std::forward<Args>(args)...)
, DataInputStream(this->storage, errorPolicy)
InputStreamWithReader<Parent, ReaderType>::InputStreamWithReader(Storage&& storage, const SoftFail&, Args&&... args)
: detail::StorageHolder<ReaderType, InputStreamWithReader<Parent, ReaderType>>(std::forward<Storage>(storage), std::forward<Args>(args)...)
, Parent(this->storage, errorPolicy)
, errorPolicy(softFail)
{}

template<class TheReader>
template<class Parent, class ReaderType>
template<class Storage, class... Args>
DataInputStream::WithReader<TheReader>::WithReader(Storage&& storage, const NoFail&, Args&&... args)
: detail::StorageHolder<TheReader, WithReader<TheReader>>(std::forward<Storage>(storage), std::forward<Args>(args)...)
, DataInputStream(this->storage, errorPolicy)
InputStreamWithReader<Parent, ReaderType>::InputStreamWithReader(Storage&& storage, const NoFail&, Args&&... args)
: detail::StorageHolder<ReaderType, InputStreamWithReader<Parent, ReaderType>>(std::forward<Storage>(storage), std::forward<Args>(args)...)
, Parent(this->storage, errorPolicy)
, errorPolicy(noFail)
{}

template<class TheReader>
DataInputStream::WithReader<TheReader>::WithReader(const WithReader& other)
: detail::StorageHolder<TheReader, WithReader<TheReader>>(static_cast<const detail::StorageHolder<TheReader, WithReader<TheReader>>&>(other))
, DataInputStream(this->storage, errorPolicy)
template<class Parent, class ReaderType>
InputStreamWithReader<Parent, ReaderType>::InputStreamWithReader(const InputStreamWithReader& other)
: detail::StorageHolder<ReaderType, InputStreamWithReader<Parent, ReaderType>>(static_cast<const detail::StorageHolder<ReaderType, InputStreamWithReader<Parent, ReaderType>>&>(other))
, Parent(this->storage, errorPolicy)
, errorPolicy(other.ErrorPolicy())
{}

template<class TheReader>
TheReader& DataInputStream::WithReader<TheReader>::Reader()
template<class Parent, class ReaderType>
ReaderType& InputStreamWithReader<Parent, ReaderType>::InputStreamWithReader::Reader()
{
return this->storage;
}

template<class TheReader>
template<class... Args>
TextInputStream::WithReader<TheReader>::WithReader(Args&&... args)
: detail::StorageHolder<TheReader, WithReader<TheReader>>(std::forward<Args>(args)...)
, TextInputStream(this->storage, errorPolicy)
template<class Parent>
InputStreamWithErrorPolicy<Parent>::InputStreamWithErrorPolicy(StreamReader& reader)
: Parent(reader, errorPolicy)
{}

template<class TheReader>
template<class Storage, class... Args>
TextInputStream::WithReader<TheReader>::WithReader(Storage&& storage, const SoftFail&, Args&&... args)
: detail::StorageHolder<TheReader, WithReader<TheReader>>(std::forward<Storage>(storage), std::forward<Args>(args)...)
, TextInputStream(this->storage, errorPolicy)
template<class Parent>
InputStreamWithErrorPolicy<Parent>::InputStreamWithErrorPolicy(StreamReader& reader, SoftFail)
: Parent(reader, errorPolicy)
, errorPolicy(softFail)
{}

template<class TheReader>
template<class Storage, class... Args>
TextInputStream::WithReader<TheReader>::WithReader(Storage&& storage, const NoFail&, Args&&... args)
: detail::StorageHolder<TheReader, WithReader<TheReader>>(std::forward<Storage>(storage), std::forward<Args>(args)...)
, TextInputStream(this->storage, errorPolicy)
template<class Parent>
InputStreamWithErrorPolicy<Parent>::InputStreamWithErrorPolicy(StreamReader& reader, NoFail)
: Parent(reader, errorPolicy)
, errorPolicy(noFail)
{}

template<class TheReader>
TextInputStream::WithReader<TheReader>::WithReader(const WithReader& other)
: detail::StorageHolder<TheReader, WithReader<TheReader>>(static_cast<detail::StorageHolder<TheReader, WithReader<TheReader>>&>(other))
, TextInputStream(this->storage, errorPolicy)
template<class Parent>
InputStreamWithErrorPolicy<Parent>::InputStreamWithErrorPolicy(const InputStreamWithErrorPolicy& other)
: Parent(other.Reader(), errorPolicy)
, errorPolicy(other.ErrorPolicy())
{}

template<class TheReader>
TheReader& TextInputStream::WithReader<TheReader>::Reader()
{
return this->storage;
}
}

#endif
38 changes: 0 additions & 38 deletions infra/stream/OutputStream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -342,44 +342,6 @@ namespace infra
Writer().Insert(MakeByteRange(width.padding), ErrorPolicy());
}

DataOutputStream::WithErrorPolicy::WithErrorPolicy(StreamWriter& writer)
: DataOutputStream(writer, errorPolicy)
{}

DataOutputStream::WithErrorPolicy::WithErrorPolicy(StreamWriter& writer, SoftFail)
: DataOutputStream(writer, errorPolicy)
, errorPolicy(softFail)
{}

DataOutputStream::WithErrorPolicy::WithErrorPolicy(StreamWriter& writer, NoFail)
: DataOutputStream(writer, errorPolicy)
, errorPolicy(noFail)
{}

DataOutputStream::WithErrorPolicy::WithErrorPolicy(const WithErrorPolicy& other)
: DataOutputStream(other.Writer(), errorPolicy)
, errorPolicy(other.ErrorPolicy())
{}

TextOutputStream::WithErrorPolicy::WithErrorPolicy(StreamWriter& writer)
: TextOutputStream(writer, errorPolicy)
{}

TextOutputStream::WithErrorPolicy::WithErrorPolicy(StreamWriter& writer, SoftFail)
: TextOutputStream(writer, errorPolicy)
, errorPolicy(softFail)
{}

TextOutputStream::WithErrorPolicy::WithErrorPolicy(StreamWriter& writer, NoFail)
: TextOutputStream(writer, errorPolicy)
, errorPolicy(noFail)
{}

TextOutputStream::WithErrorPolicy::WithErrorPolicy(const WithErrorPolicy& other)
: TextOutputStream(other.Writer(), errorPolicy)
, errorPolicy(other.ErrorPolicy())
{}

AsAsciiHelper::AsAsciiHelper(ConstByteRange data)
: data(data)
{}
Expand Down
Loading

0 comments on commit 5015938

Please sign in to comment.