Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions example/print_example.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,24 @@ int main()
queue_data.push(300);
std::cout << print_queue(queue_data, "IntQueue") << "\n";

// --- 部分打印示例 (Partial Container Printing) ---
std::cout << "--- Container Partial Head/Tail ---" << "\n";

std::vector<int> long_vec{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
auto long_vec_printer = print_vector(long_vec, "LongVec");
long_vec_printer.enable_partial(true)
.set_head_tail_count(2, 2)
.set_partial_ellipsis("...");
std::cout << long_vec_printer << "\n";

std::map<std::string, int> long_map{{"a", 1}, {"b", 2}, {"c", 3},
{"d", 4}, {"e", 5}, {"f", 6}};
auto long_map_printer = print_map(long_map, "LongMap");
long_map_printer.enable_partial(true)
.set_head_tail_count(1, 1)
.set_partial_ellipsis("...");
std::cout << long_map_printer << "\n";

// --- 自定义样式示例 (Custom Style Example) ---
std::cout << "--- Custom Style Examples ---" << "\n";

Expand Down
22 changes: 22 additions & 0 deletions src/impl/cpp-toolbox/utils/print.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ table_t::table_t(const print_style_t& style)
, m_highlight_cb(nullptr)
, m_out_color(true)
, m_file_color(false)
, m_title()
, m_footer()
{
}

Expand All @@ -111,6 +113,20 @@ table_t& table_t::add_row(const std::vector<std::string>& row)
return *this;
}

/** @brief 设置表格标题 / Set table title */
table_t& table_t::set_title(const std::string& title)
{
m_title = title;
return *this;
}

/** @brief 设置表格尾部文本 / Set table footer */
table_t& table_t::set_footer(const std::string& footer)
{
m_footer = footer;
return *this;
}

/** @brief 设置列固定宽度 / Set fixed column width */
table_t& table_t::set_column_width(size_t col, size_t width)
{
Expand Down Expand Up @@ -418,6 +434,9 @@ std::ostream& operator<<(std::ostream& os, const table_t& tbl)
if (tbl.m_headers.empty()) {
return os << "[Empty table]\n";
}
if (!tbl.m_title.empty()) {
os << tbl.m_title << '\n';
}
tbl.calculate_col_widths();
tbl.print_horizontal_border(os, table_t::border_pos_t::TOP);
if (tbl.m_style.show_header) {
Expand All @@ -431,6 +450,9 @@ std::ostream& operator<<(std::ostream& os, const table_t& tbl)
i + (tbl.m_style.show_header ? 1 : 0));
}
tbl.print_horizontal_border(os, table_t::border_pos_t::BOTTOM);
if (!tbl.m_footer.empty()) {
os << tbl.m_footer << '\n';
}
return os;
}

Expand Down
149 changes: 143 additions & 6 deletions src/include/cpp-toolbox/utils/print.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -518,6 +518,20 @@ class CPP_TOOLBOX_EXPORT table_t
return this->add_row(row_data);
}

/**
* @brief 设置表格标题 / Set table title text
* @param title 标题文本 / Title text
* @return table_t& 当前对象的引用 / Reference to this table_t
*/
table_t& set_title(const std::string& title);

/**
* @brief 设置表格尾部文本 / Set table footer text
* @param footer 尾部文本 / Footer text
* @return table_t& 当前对象的引用 / Reference to this table_t
*/
table_t& set_footer(const std::string& footer);

/**
* @brief 设置指定列的对齐方式 / Set alignment for a specific column
* @param column_index 列索引 / Column index
Expand Down Expand Up @@ -656,6 +670,12 @@ class CPP_TOOLBOX_EXPORT table_t
/** @brief 打印风格 / Base print style */
print_style_t m_style;

/** @brief 表格标题文本 / Table title text */
std::string m_title;

/** @brief 表格尾部文本 / Table footer text */
std::string m_footer;

/** @brief 列固定宽度映射 (col -> width) / Map of column to fixed width */
std::unordered_map<size_t, size_t> m_col_fixed_width;

Expand Down Expand Up @@ -760,6 +780,10 @@ class CPP_TOOLBOX_EXPORT container_printer_t
const Container& m_container; ///< 容器引用/Container reference
std::string m_name; ///< 容器名称/Container name
print_style_t m_style; ///< 打印风格/Print style
bool m_partial{false}; ///< 是否启用首尾打印/Enable head-tail printing
size_t m_head_count{3}; ///< 头部元素数量/Number of head elements
size_t m_tail_count{3}; ///< 尾部元素数量/Number of tail elements
std::string m_partial_ellipsis{"..."}; ///< 省略符/Ellipsis when truncated

protected:
/**
Expand Down Expand Up @@ -807,6 +831,45 @@ class CPP_TOOLBOX_EXPORT container_printer_t
{
}

/**
* @brief 启用或禁用首尾打印/Enable or disable head-tail printing
* @param enable 是否启用/Enable flag
* @return container_printer_t& 当前对象引用/Reference to this
*/
container_printer_t& enable_partial(bool enable)
{
m_partial = enable;
return *this;
}

/**
* @brief 设置头尾元素数量/Set head and tail element counts
*/
container_printer_t& set_head_tail_count(size_t head, size_t tail)
{
m_head_count = head;
m_tail_count = tail;
return *this;
}

/**
* @brief 设置省略符/Set ellipsis string for partial printing
*/
container_printer_t& set_partial_ellipsis(const std::string& ellipsis)
{
m_partial_ellipsis = ellipsis;
return *this;
}

protected:
[[nodiscard]] auto partial_enabled() const -> bool { return m_partial; }
[[nodiscard]] auto head_count() const -> size_t { return m_head_count; }
[[nodiscard]] auto tail_count() const -> size_t { return m_tail_count; }
[[nodiscard]] auto ellipsis() const -> const std::string&
{
return m_partial_ellipsis;
}

/**
* @brief 析构函数/Destructor
*/
Expand Down Expand Up @@ -884,7 +947,13 @@ class CPP_TOOLBOX_EXPORT vector_printer_t
*/
void print_content(std::ostream& os) const override
{
for (size_t i = 0; i < this->get_container().size(); ++i) {
size_t total = this->get_container().size();
bool partial = this->partial_enabled() &&
total > (this->head_count() + this->tail_count());
size_t head = partial ? this->head_count() : total;
size_t tail_start = partial ? total - this->tail_count() : total;

for (size_t i = 0; i < head; ++i) {
const std::string index = "[" + std::to_string(i) + "]: ";
const std::string value = to_string_value(this->get_container()[i]);

Expand All @@ -898,7 +967,35 @@ class CPP_TOOLBOX_EXPORT vector_printer_t
: value;

os << " " << colored_index << colored_value;
if (i < this->get_container().size() - 1) {
if (partial || i < total - 1) {
os << ",";
}
os << "\n";
}

if (partial) {
os << " " << this->ellipsis();
if (tail_start < total) {
os << ",";
}
os << "\n";
}

for (size_t i = std::max(head, tail_start); i < total; ++i) {
const std::string index = "[" + std::to_string(i) + "]: ";
const std::string value = to_string_value(this->get_container()[i]);

const std::string colored_index = this->get_style().use_colors
? color_handler_t::colorize(
index, this->get_style().header_fg, color_t::DEFAULT)
: index;
const std::string colored_value = this->get_style().use_colors
? color_handler_t::colorize(
value, this->get_style().data_fg, color_t::DEFAULT)
: value;

os << " " << colored_index << colored_value;
if (i < total - 1) {
os << ",";
}
os << "\n";
Expand Down Expand Up @@ -939,8 +1036,17 @@ class CPP_TOOLBOX_EXPORT map_printer_t
*/
void print_content(std::ostream& os) const override
{
size_t i = 0;
for (const auto& [key, value] : this->get_container()) {
size_t total = this->get_container().size();
bool partial = this->partial_enabled() &&
total > (this->head_count() + this->tail_count());
size_t head = partial ? this->head_count() : total;
size_t tail_start = partial ? total - this->tail_count() : total;

size_t idx = 0;
for (auto it = this->get_container().begin();
it != this->get_container().end() && idx < head; ++it, ++idx)
{
const auto& [key, value] = *it;
const std::string key_str = to_string_value(key);
const std::string value_str = to_string_value(value);
const std::string arrow = " => ";
Expand All @@ -955,11 +1061,42 @@ class CPP_TOOLBOX_EXPORT map_printer_t
: value_str;

os << " " << colored_key << arrow << colored_value;
if (i < this->get_container().size() - 1) {
if (partial || idx < total - 1) {
os << ",";
}
os << "\n";
i++;
}

if (partial) {
os << " " << this->ellipsis();
if (tail_start < total) {
os << ",";
}
os << "\n";

auto it = this->get_container().begin();
std::advance(it, tail_start);
for (; it != this->get_container().end(); ++it) {
const auto& [key, value] = *it;
const std::string key_str = to_string_value(key);
const std::string value_str = to_string_value(value);
const std::string arrow = " => ";

const std::string colored_key = this->get_style().use_colors
? color_handler_t::colorize(
key_str, this->get_style().header_fg, color_t::DEFAULT)
: key_str;
const std::string colored_value = this->get_style().use_colors
? color_handler_t::colorize(
value_str, this->get_style().data_fg, color_t::DEFAULT)
: value_str;

os << " " << colored_key << arrow << colored_value;
if (std::next(it) != this->get_container().end()) {
os << ",";
}
os << "\n";
}
}
}

Expand Down