Skip to content

Commit

Permalink
Changed fmt formatters to make use of overloaded operator insertion.
Browse files Browse the repository at this point in the history
Fixed an issue in problem 66: binary_search was used in an unordered vector.
  • Loading branch information
rturrado committed Nov 6, 2022
1 parent a8f3a66 commit 8ae6719
Show file tree
Hide file tree
Showing 19 changed files with 264 additions and 846 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -424,49 +424,33 @@ namespace tmcppc::data_structures {
return column_widths;
}

private:
friend struct fmt::formatter<array_2d>;
friend std::ostream& operator<<(std::ostream& os, const array_2d<T>& arr) {
if (arr.empty()) {
os << fmt::format("{}", "[]");
} else {
auto column_widths{ get_column_widths(arr) };

for (size_t row{ 0 }; row < arr.height_; ++row) {
os << fmt::format("{}{}", (row == 0 ? "" : "\n"), "[ ");
for (size_t col{ 0 }; col < arr.width_; ++col) {
os << fmt::format("{0}{2:>{1}}", (col == 0 ? "" : ", "), column_widths[col], arr.at(row, col));
}
os << fmt::format("{}", " ]");
}
}
return os;
}

private:
std::vector<T> data_;
size_type width_;
size_type height_;
};
} // namespace tmcppc::data_structures


// fmt formatters
template <rtc::print::printable T>
struct fmt::is_range<tmcppc::data_structures::array_2d<T>, char> : std::false_type {};


template <rtc::print::printable T>
struct fmt::formatter<tmcppc::data_structures::array_2d<T>> {
template <typename ParseContext>
constexpr auto parse(ParseContext& ctx) {
return ctx.begin();
}

template <typename FormatContext>
auto format(const tmcppc::data_structures::array_2d<T>& arr, FormatContext& ctx) const -> decltype(ctx.out()) {
if (arr.empty()) {
fmt::format_to(ctx.out(), "{}", "[]");
} else {
auto column_widths{ get_column_widths(arr) };

for (size_t row{ 0 }; row < arr.height_; ++row) {
fmt::format_to(ctx.out(), "{}{}", (row == 0 ? "" : "\n"), "[ ");
for (size_t col{ 0 }; col < arr.width_; ++col) {
fmt::format_to(ctx.out(), "{0}{2:>{1}}", (col == 0 ? "" : ", "), column_widths[col], arr.at(row, col));
}
fmt::format_to(ctx.out(), "{}", " ]");
}
}
return ctx.out();
}
};


template <rtc::print::printable T>
std::ostream& operator<<(std::ostream& os, const tmcppc::data_structures::array_2d<T>& arr) {
fmt::print(os, "{}", arr);
return os;
}
struct fmt::formatter<tmcppc::data_structures::array_2d<T>> : fmt::ostream_formatter {};
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@
#include <string>


// fmt formatter
namespace tmcppc::network { class ipv4; }
template <>
struct fmt::formatter<tmcppc::network::ipv4> : fmt::ostream_formatter {};


namespace tmcppc::network {
struct invalid_ipv4_address_error : public std::runtime_error {
explicit invalid_ipv4_address_error(const std::string& address) : std::runtime_error{ "" } {
Expand Down Expand Up @@ -65,7 +71,9 @@ namespace tmcppc::network {
: octets_{ o0, o1, o2, o3 }
{}

[[nodiscard]] std::string to_string() const;
[[nodiscard]] std::string to_string() const {
return fmt::format("{}", *this);
}

[[nodiscard]] constexpr unsigned long to_ulong() const noexcept {
return static_cast<unsigned long>((octets_[0] << 24) | (octets_[1] << 16) | (octets_[2] << 8) | octets_[3]);
Expand All @@ -82,7 +90,7 @@ namespace tmcppc::network {
return tmp;
}

private:
public:
friend bool operator==(const ipv4& lhs, const ipv4& rhs) {
return lhs.octets_ == rhs.octets_;
}
Expand Down Expand Up @@ -139,30 +147,6 @@ namespace tmcppc::network {
}

private:
friend struct fmt::formatter<ipv4>;

std::array<std::uint8_t, 4> octets_{};
};
} // namespace tmcppc::network


template <>
struct fmt::formatter<tmcppc::network::ipv4> {
template <typename ParseContext>
constexpr auto parse(ParseContext& ctx) {
return ctx.begin();
}

template <typename FormatContext>
auto format(const tmcppc::network::ipv4& address, FormatContext& ctx) const -> decltype(ctx.out()) {
return fmt::format_to(ctx.out(), "{}.{}.{}.{}",
address.octets_[0], address.octets_[1], address.octets_[2], address.octets_[3]);
}
};


namespace tmcppc::network {
[[nodiscard]] inline std::string ipv4::to_string() const {
return fmt::format("{}", *this);
}
} // namespace tmcppc::network
Original file line number Diff line number Diff line change
Expand Up @@ -66,24 +66,22 @@ namespace tmcppc::temperature::v1 {
return *this;
}

friend std::ostream& operator<<(std::ostream& os, const temperature<Rep_>& t) {
const auto& s{ t.scale_ };
if (s == tmcppc::temperature::v1::scale_t::invalid) {
return os << fmt::format("{}", to_string(s));
}
return os << fmt::format("{:.2f} {}", t.value_, to_string(s));
}

[[nodiscard]] Rep_ value() const noexcept { return value_; }
[[nodiscard]] scale_t scale() const noexcept { return scale_; }

private:
friend struct fmt::formatter<temperature>;

Rep_ value_{ 0 };
enum scale_t scale_{ scale_t::invalid };
};

// Operator insertion
//
template <typename Rep_>
std::ostream& operator<<(std::ostream& os, const temperature<Rep_>& t) {
fmt::print(os, "{}", t);
return os;
}

// Conversions
//
// C to F: (C * 9/5) + 32
Expand Down Expand Up @@ -217,19 +215,6 @@ namespace tmcppc::temperature::v1 {
} // namespace tmcppc::temperature::v1


// fmt formatter
template <typename Rep_>
struct fmt::formatter<tmcppc::temperature::v1::temperature<Rep_>> {
template <typename ParseContext>
constexpr auto parse(ParseContext& ctx) {
return ctx.begin();
}

template <typename FormatContext>
auto format(const tmcppc::temperature::v1::temperature<Rep_>& t, FormatContext& ctx) const -> decltype(ctx.out()) {
const auto& s{ t.scale() };
if (s == tmcppc::temperature::v1::scale_t::invalid) {
return fmt::format_to(ctx.out(), "{}", to_string(s));
}
return fmt::format_to(ctx.out(), "{:.2f} {}", t.value(), to_string(s));
}
};
struct fmt::formatter<tmcppc::temperature::v1::temperature<Rep_>> : fmt::ostream_formatter {};
Original file line number Diff line number Diff line change
Expand Up @@ -55,18 +55,15 @@ namespace tmcppc::temperature::v2 {
//
template <typename Rep_>
std::ostream& operator<<(std::ostream& os, const temperature<Rep_, scale_t::celsius>& t) {
fmt::print(os, "{:.2f} Celsius", t.value());
return os;
return os << fmt::format("{:.2f} Celsius", t.value());
}
template <typename Rep_>
std::ostream& operator<<(std::ostream& os, const temperature<Rep_, scale_t::fahrenheit>& t) {
fmt::print(os, "{:.2f} Fahrenheit", t.value());
return os;
return os << fmt::format("{:.2f} Fahrenheit", t.value());
}
template <typename Rep_>
std::ostream& operator<<(std::ostream& os, const temperature<Rep_, scale_t::kelvin>& t) {
fmt::print(os, "{:.2f} Kelvin", t.value());
return os;
return os << fmt::format("{:.2f} Kelvin", t.value());
}

// Conversions
Expand Down Expand Up @@ -192,47 +189,10 @@ namespace tmcppc::temperature::v2 {
} // namespace tmcppc::temperature::v2


// fmt formatters
template <typename Rep_>
struct fmt::formatter<tmcppc::temperature::v2::temperature<Rep_, tmcppc::temperature::v2::scale_t::celsius>> {
template <typename ParseContext>
constexpr auto parse(ParseContext& ctx) {
return ctx.begin();
}

template <typename FormatContext>
auto format(const tmcppc::temperature::v2::temperature<Rep_, tmcppc::temperature::v2::scale_t::celsius>& t,
FormatContext& ctx) const -> decltype(ctx.out()) {

return fmt::format_to(ctx.out(), "{:.2f} Celsius", t.value());
}
};

struct fmt::formatter<tmcppc::temperature::v2::temperature<Rep_, tmcppc::temperature::v2::scale_t::celsius>> : fmt::ostream_formatter {};
template <typename Rep_>
struct fmt::formatter<tmcppc::temperature::v2::temperature<Rep_, tmcppc::temperature::v2::scale_t::fahrenheit>> {
template <typename ParseContext>
constexpr auto parse(ParseContext& ctx) {
return ctx.begin();
}

template <typename FormatContext>
auto format(const tmcppc::temperature::v2::temperature<Rep_, tmcppc::temperature::v2::scale_t::fahrenheit>& t,
FormatContext& ctx) const -> decltype(ctx.out()) {

return fmt::format_to(ctx.out(), "{:.2f} Fahrenheit", t.value());
}
};

struct fmt::formatter<tmcppc::temperature::v2::temperature<Rep_, tmcppc::temperature::v2::scale_t::fahrenheit>> : fmt::ostream_formatter {};
template <typename Rep_>
struct fmt::formatter<tmcppc::temperature::v2::temperature<Rep_, tmcppc::temperature::v2::scale_t::kelvin>> {
template <typename ParseContext>
constexpr auto parse(ParseContext& ctx) {
return ctx.begin();
}

template <typename FormatContext>
auto format(const tmcppc::temperature::v2::temperature<Rep_, tmcppc::temperature::v2::scale_t::kelvin>& t,
FormatContext& ctx) const -> decltype(ctx.out()) {

return fmt::format_to(ctx.out(), "{:.2f} Kelvin", t.value());
}
};
struct fmt::formatter<tmcppc::temperature::v2::temperature<Rep_, tmcppc::temperature::v2::scale_t::kelvin>> : fmt::ostream_formatter {};
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,29 @@ namespace tmcppc::network {

auto operator<=>(const url& other) const = default;

private:
friend struct fmt::formatter<url>;
friend std::ostream& operator<<(std::ostream& os, const tmcppc::network::url& u) {
os << fmt::format("[\n");
os << fmt::format("\tProtocol: {}\n", u.protocol_);
if (u.login_.has_value()) {
os << fmt::format("\tLogin: {}\n", u.login_.value());
}
os << fmt::format("\tDomain: {}\n", u.domain_);
if (u.port_.has_value()) {
os << fmt::format("\tPort: {}\n", u.port_.value());
}
if (u.path_.has_value()) {
os << fmt::format("\tPath: {}\n", u.path_.value());
}
if (u.query_.has_value()) {
os << fmt::format("\tQuery: {}\n", u.query_.value());
}
if (u.fragment_.has_value()) {
os << fmt::format("\tFragment: {}\n", u.fragment_.value());
}
return os << fmt::format("]");
}

private:
std::string protocol_;
std::optional<std::string> login_;
std::string domain_;
Expand All @@ -81,39 +101,6 @@ namespace tmcppc::network {
} // namespace tmcppc::network


// fmt formatter
template <>
struct fmt::formatter<tmcppc::network::url> {
template <typename ParseContext>
constexpr auto parse(ParseContext& ctx) {
return ctx.begin();
}

template <typename FormatContext>
auto format(const tmcppc::network::url& u, FormatContext& ctx) const -> decltype(ctx.out()) {
fmt::format_to(ctx.out(), "[\n");
fmt::format_to(ctx.out(), "\tProtocol: {}\n", u.protocol_);
if (u.login_.has_value()) {
fmt::format_to(ctx.out(), "\tLogin: {}\n", u.login_.value());
}
fmt::format_to(ctx.out(), "\tDomain: {}\n", u.domain_);
if (u.port_.has_value()) {
fmt::format_to(ctx.out(), "\tPort: {}\n", u.port_.value());
}
if (u.path_.has_value()) {
fmt::format_to(ctx.out(), "\tPath: {}\n", u.path_.value());
}
if (u.query_.has_value()) {
fmt::format_to(ctx.out(), "\tQuery: {}\n", u.query_.value());
}
if (u.fragment_.has_value()) {
fmt::format_to(ctx.out(), "\tFragment: {}\n", u.fragment_.value());
}
fmt::format_to(ctx.out(), "]");
return ctx.out();
}
};

inline std::ostream& operator<<(std::ostream& os, const tmcppc::network::url& u) {
fmt::print(os, "{}", u);
return os;
}
struct fmt::formatter<tmcppc::network::url> : fmt::ostream_formatter {};
Loading

0 comments on commit 8ae6719

Please sign in to comment.