Skip to content

Commit

Permalink
external toString functions
Browse files Browse the repository at this point in the history
Signed-off-by: Mikhail Boldyrev <miboldyrev@gmail.com>
  • Loading branch information
MBoldyrev committed Jan 21, 2020
1 parent 60a654f commit 45c9dd4
Show file tree
Hide file tree
Showing 9 changed files with 264 additions and 81 deletions.
2 changes: 1 addition & 1 deletion irohad/ametsuchi/impl/postgres_command_executor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -387,7 +387,7 @@ namespace iroha {
command_name_(std::move(command_name)),
perm_converter_(std::move(perm_converter)) {
arguments_string_builder_.init(command_name_)
.append("Validation", enable_validation);
.appendNamed("Validation", enable_validation);
}

template <typename T,
Expand Down
2 changes: 1 addition & 1 deletion irohad/consensus/yac/vote_message.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ namespace iroha {
std::string toString() const {
return shared_model::detail::PrettyStringBuilder()
.init("VoteMessage")
.append("yac hash", hash.toString())
.appendNamed("yac hash", hash)
.appendNamed("signature", signature)
.finalize();
}
Expand Down
7 changes: 7 additions & 0 deletions libs/common/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,13 @@ target_link_libraries(libs_timeout INTERFACE

add_library(irohad_version irohad_version.cpp)

add_library(libs_to_string INTERFACE
# to_string.hpp
)
target_link_libraries(libs_to_string INTERFACE
Boost::boost
)

# Get the git repo data
set(GIT_REPO_PRETTY_VER "version info unavailable")
if (EXISTS "${PROJECT_SOURCE_DIR}/.git")
Expand Down
104 changes: 104 additions & 0 deletions libs/common/to_string.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
/**
* Copyright Soramitsu Co., Ltd. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/

#ifndef IROHA_LIBS_TO_STRING_HPP
#define IROHA_LIBS_TO_STRING_HPP

#include <memory>
#include <string>

#include <boost/optional.hpp>

namespace iroha {
namespace to_string {
namespace detail {
const std::string kBeginBlockMarker = "[";
const std::string kEndBlockMarker = "]";
const std::string kSingleFieldsSeparator = ", ";
const std::string kNotSet = "(not set)";

/// Print pointers and optionals.
template <typename T>
inline std::string toStringDereferenced(const T &o);
} // namespace detail

inline std::string toString(const std::string &o) {
return o;
}

template <typename T>
inline auto toString(const T &o) -> std::enable_if_t<
std::is_same<decltype(std::to_string(o)), std::string>::value,
std::string> {
return std::to_string(o);
}

template <typename T>
inline auto toString(const T &o) -> std::enable_if_t<
std::is_same<typename std::decay_t<decltype(o.toString())>,
std::string>::value,
std::string> {
return o.toString();
}

template <typename... T>
inline std::string toString(const std::unique_ptr<T...> &o) {
return detail::toStringDereferenced(o);
}

template <typename... T>
inline std::string toString(const std::shared_ptr<T...> &o) {
return detail::toStringDereferenced(o);
}

template <typename T>
inline std::string toString(const T *o) {
return detail::toStringDereferenced(o);
}

template <typename T>
inline auto toString(const T &o) -> std::enable_if_t<
boost::optional_detail::is_optional_related<T>::value,
std::string> {
return detail::toStringDereferenced(o);
}

/// Print a plain collection.
template <typename T, typename = decltype(*std::declval<T>().begin())>
inline std::string toString(const T &c) {
std::string result = detail::kBeginBlockMarker;
bool need_field_separator = false;
for (auto &o : c) {
if (need_field_separator) {
result.append(detail::kSingleFieldsSeparator);
}
result.append(toString(o));
need_field_separator = true;
}
result.append(detail::kEndBlockMarker);
return result;
}

namespace detail {
/// Print pointers and optionals.
template <typename T>
inline std::string toStringDereferenced(const T &o) {
if (o) {
return ::iroha::to_string::toString(*o);
} else {
return kNotSet;
}
}

template <>
inline std::string toStringDereferenced<boost::none_t>(
const boost::none_t &) {
return kNotSet;
}
} // namespace detail
} // namespace to_string
} // namespace iroha

#endif
3 changes: 3 additions & 0 deletions shared_model/utils/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,6 @@
add_library(shared_model_utils
string_builder.cpp
)
target_link_libraries(shared_model_utils
libs_to_string
)
6 changes: 1 addition & 5 deletions shared_model/utils/string_builder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ namespace shared_model {

PrettyStringBuilder &PrettyStringBuilder::append(const std::string &value) {
appendPartial(value);
setElementBoundary();
need_field_separator_ = true;
return *this;
}

Expand All @@ -49,10 +49,6 @@ namespace shared_model {
result_.append(value);
}

void PrettyStringBuilder::setElementBoundary() {
need_field_separator_ = true;
}

std::string PrettyStringBuilder::finalize() {
removeLevel();
return result_;
Expand Down
84 changes: 10 additions & 74 deletions shared_model/utils/string_builder.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

#include <string>

#include "common/to_string.hpp"

namespace shared_model {
namespace detail {
/**
Expand Down Expand Up @@ -36,35 +38,24 @@ namespace shared_model {
PrettyStringBuilder &append(const std::string &o);

template <typename T>
auto append(const T &o) -> std::enable_if_t<
std::is_same<decltype(std::to_string(o)), std::string>::value,
PrettyStringBuilder &>;

template <typename T>
auto append(const T &o) -> std::enable_if_t<
std::is_same<typename std::decay_t<decltype(o.toString())>,
std::string>::value,
PrettyStringBuilder &>;

/// Append pointers and optionals.
template <typename T>
auto append(const T &o) -> std::enable_if_t<not std::is_array<T>::value,
decltype(append(*o))>;
PrettyStringBuilder &append(const T &o) {
return append(iroha::to_string::toString(o));
}

/// ---------- Augmented appending functions. ---------- ///

/// Append a plain collection.
template <typename T>
auto append(const T &c) -> decltype(append(*c.begin()));

/**
* Appends new field to string as a "name=value" pair
* @param name - field name to append
* @param value - field value
*/
template <typename Value>
PrettyStringBuilder &appendNamed(const std::string &name,
const Value &value);
const Value &value) {
appendPartial(name);
appendPartial(keyValueSeparator);
return append(iroha::to_string::toString(value));
}

/**
* Finalizes appending and returns constructed string.
Expand All @@ -74,7 +65,6 @@ namespace shared_model {

private:
void appendPartial(const std::string &);
void setElementBoundary();
std::string result_;
bool need_field_separator_;
static const std::string beginBlockMarker;
Expand All @@ -84,60 +74,6 @@ namespace shared_model {
static const std::string initSeparator;
static const std::string spaceSeparator;
};

template <typename T>
auto PrettyStringBuilder::append(const T &o) -> std::enable_if_t<
std::is_same<decltype(std::to_string(o)), std::string>::value,
PrettyStringBuilder &> {
return append(std::to_string(o));
}

template <typename T>
auto PrettyStringBuilder::append(const T &o) -> std::enable_if_t<
std::is_same<typename std::decay_t<decltype(o.toString())>,
std::string>::value,
PrettyStringBuilder &> {
return append(o.toString());
}

/// Append pointers and optionals.
template <typename T>
auto PrettyStringBuilder::append(const T &o)
-> std::enable_if_t<not std::is_array<T>::value, decltype(append(*o))> {
if (o) {
return append(*o);
} else {
return append("(not set)");
}
}

/// ---------- Augmented appending functions. ---------- ///

/// Append a plain collection.
template <typename T>
auto PrettyStringBuilder::append(const T &c)
-> decltype(append(*c.begin())) {
insertLevel();
for (auto &o : c) {
append(o);
}
removeLevel();
return *this;
}

/**
* Appends new field to string as a "name=value" pair
* @param name - field name to append
* @param value - field value
*/
template <typename Value>
PrettyStringBuilder &PrettyStringBuilder::appendNamed(
const std::string &name, const Value &value) {
appendPartial(name);
appendPartial(keyValueSeparator);
return append(value);
}

} // namespace detail
} // namespace shared_model

Expand Down
5 changes: 5 additions & 0 deletions test/module/libs/common/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@
# SPDX-License-Identifier: Apache-2.0
#

addtest(to_string_test to_string_test.cpp)
target_link_libraries(to_string_test
common
)

addtest(result_test result_test.cpp)
target_link_libraries(result_test
common
Expand Down

0 comments on commit 45c9dd4

Please sign in to comment.