diff --git a/CMakeLists.txt b/CMakeLists.txt index 834ce92..c11bf9d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.24) project(BLT) -set(CMAKE_PROJECT_VERSION 0.2a) +set(CMAKE_PROJECT_VERSION 0.3a) set(CMAKE_CXX_STANDARD 17) option(BUILD_STD "Build the BLT standard utilities." ON) diff --git a/cmake-build-release/CMakeFiles/clion-Release-log.txt b/cmake-build-release/CMakeFiles/clion-Release-log.txt index 8fad002..5275a66 100644 --- a/cmake-build-release/CMakeFiles/clion-Release-log.txt +++ b/cmake-build-release/CMakeFiles/clion-Release-log.txt @@ -1,10 +1,10 @@ /opt/netbrains/clion/clion-2022.1.3/bin/cmake/linux/bin/cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_MAKE_PROGRAM=/opt/netbrains/clion/clion-2022.1.3/bin/ninja/linux/ninja -DBUILD_TESTS:BOOL=ON -G Ninja -S /home/brett/Documents/code/c++/BLT -B /home/brett/Documents/code/c++/BLT/cmake-build-release -- Detected PHMAP Version - 1.3.8 -Standard Files /home/brett/Documents/code/c++/BLT/src/blt/std/logging.cpp;/home/brett/Documents/code/c++/BLT/src/blt/std/queues.cpp;/home/brett/Documents/code/c++/BLT/src/blt/std/random.cpp;/home/brett/Documents/code/c++/BLT/src/blt/std/string.cpp;/home/brett/Documents/code/c++/BLT/src/blt/std/system.cpp +Standard Files /home/brett/Documents/code/c++/BLT/src/blt/std/format.cpp;/home/brett/Documents/code/c++/BLT/src/blt/std/logging.cpp;/home/brett/Documents/code/c++/BLT/src/blt/std/system.cpp Profiler Files /home/brett/Documents/code/c++/BLT/src/blt/profiling/profiler.cpp Source: /home/brett/Documents/code/c++/BLT Current Source: /home/brett/Documents/code/c++/BLT -BLT 0.2a Successfully included! +BLT 0.3a Successfully included! BLT tests included! -- Configuring done -- Generating done diff --git a/cmake-build-release/build.ninja b/cmake-build-release/build.ninja index a04a168..2878899 100644 --- a/cmake-build-release/build.ninja +++ b/cmake-build-release/build.ninja @@ -49,6 +49,13 @@ cmake_ninja_workdir = /home/brett/Documents/code/c++/BLT/cmake-build-release/ build cmake_object_order_depends_target_BLT: phony || CMakeFiles/BLT.dir +build CMakeFiles/BLT.dir/src/blt/std/format.cpp.o: CXX_COMPILER__BLT_Release /home/brett/Documents/code/c++/BLT/src/blt/std/format.cpp || cmake_object_order_depends_target_BLT + DEP_FILE = CMakeFiles/BLT.dir/src/blt/std/format.cpp.o.d + FLAGS = -O3 -DNDEBUG -fdiagnostics-color=always + INCLUDES = -I/home/brett/Documents/code/c++/BLT/include + OBJECT_DIR = CMakeFiles/BLT.dir + OBJECT_FILE_DIR = CMakeFiles/BLT.dir/src/blt/std + build CMakeFiles/BLT.dir/src/blt/std/logging.cpp.o: CXX_COMPILER__BLT_Release /home/brett/Documents/code/c++/BLT/src/blt/std/logging.cpp || cmake_object_order_depends_target_BLT DEP_FILE = CMakeFiles/BLT.dir/src/blt/std/logging.cpp.o.d FLAGS = -O3 -DNDEBUG -fdiagnostics-color=always @@ -56,27 +63,6 @@ build CMakeFiles/BLT.dir/src/blt/std/logging.cpp.o: CXX_COMPILER__BLT_Release /h OBJECT_DIR = CMakeFiles/BLT.dir OBJECT_FILE_DIR = CMakeFiles/BLT.dir/src/blt/std -build CMakeFiles/BLT.dir/src/blt/std/queues.cpp.o: CXX_COMPILER__BLT_Release /home/brett/Documents/code/c++/BLT/src/blt/std/queues.cpp || cmake_object_order_depends_target_BLT - DEP_FILE = CMakeFiles/BLT.dir/src/blt/std/queues.cpp.o.d - FLAGS = -O3 -DNDEBUG -fdiagnostics-color=always - INCLUDES = -I/home/brett/Documents/code/c++/BLT/include - OBJECT_DIR = CMakeFiles/BLT.dir - OBJECT_FILE_DIR = CMakeFiles/BLT.dir/src/blt/std - -build CMakeFiles/BLT.dir/src/blt/std/random.cpp.o: CXX_COMPILER__BLT_Release /home/brett/Documents/code/c++/BLT/src/blt/std/random.cpp || cmake_object_order_depends_target_BLT - DEP_FILE = CMakeFiles/BLT.dir/src/blt/std/random.cpp.o.d - FLAGS = -O3 -DNDEBUG -fdiagnostics-color=always - INCLUDES = -I/home/brett/Documents/code/c++/BLT/include - OBJECT_DIR = CMakeFiles/BLT.dir - OBJECT_FILE_DIR = CMakeFiles/BLT.dir/src/blt/std - -build CMakeFiles/BLT.dir/src/blt/std/string.cpp.o: CXX_COMPILER__BLT_Release /home/brett/Documents/code/c++/BLT/src/blt/std/string.cpp || cmake_object_order_depends_target_BLT - DEP_FILE = CMakeFiles/BLT.dir/src/blt/std/string.cpp.o.d - FLAGS = -O3 -DNDEBUG -fdiagnostics-color=always - INCLUDES = -I/home/brett/Documents/code/c++/BLT/include - OBJECT_DIR = CMakeFiles/BLT.dir - OBJECT_FILE_DIR = CMakeFiles/BLT.dir/src/blt/std - build CMakeFiles/BLT.dir/src/blt/std/system.cpp.o: CXX_COMPILER__BLT_Release /home/brett/Documents/code/c++/BLT/src/blt/std/system.cpp || cmake_object_order_depends_target_BLT DEP_FILE = CMakeFiles/BLT.dir/src/blt/std/system.cpp.o.d FLAGS = -O3 -DNDEBUG -fdiagnostics-color=always @@ -99,7 +85,7 @@ build CMakeFiles/BLT.dir/src/blt/profiling/profiler.cpp.o: CXX_COMPILER__BLT_Rel ############################################# # Link the static library libBLT.a -build libBLT.a: CXX_STATIC_LIBRARY_LINKER__BLT_Release CMakeFiles/BLT.dir/src/blt/std/logging.cpp.o CMakeFiles/BLT.dir/src/blt/std/queues.cpp.o CMakeFiles/BLT.dir/src/blt/std/random.cpp.o CMakeFiles/BLT.dir/src/blt/std/string.cpp.o CMakeFiles/BLT.dir/src/blt/std/system.cpp.o CMakeFiles/BLT.dir/src/blt/profiling/profiler.cpp.o +build libBLT.a: CXX_STATIC_LIBRARY_LINKER__BLT_Release CMakeFiles/BLT.dir/src/blt/std/format.cpp.o CMakeFiles/BLT.dir/src/blt/std/logging.cpp.o CMakeFiles/BLT.dir/src/blt/std/system.cpp.o CMakeFiles/BLT.dir/src/blt/profiling/profiler.cpp.o LANGUAGE_COMPILE_FLAGS = -O3 -DNDEBUG OBJECT_DIR = CMakeFiles/BLT.dir POST_BUILD = : diff --git a/design.txt b/design.txt index 619f32d..cabf5c7 100644 --- a/design.txt +++ b/design.txt @@ -1,4 +1,4 @@ -//Utility classes start with captials (IE classes which are purely static) Utility classes are namespaces all lower case. -everything else is camel cased underscore to conform to what most of the C libs seem to use -Template types should be capital camel case +standard classes are Camel Cased. +data structure classes are snake cased. (to conform to what most of the C libs seem to use) +Template types should be capital snake case diff --git a/include/blt/std/format.h b/include/blt/std/format.h new file mode 100644 index 0000000..2a7fdff --- /dev/null +++ b/include/blt/std/format.h @@ -0,0 +1,97 @@ +/* + * Created by Brett on 26/01/23. + * Licensed under GNU General Public License V3.0 + * See LICENSE file for license detail + */ + +#ifndef BLT_TESTS_FORMAT_H +#define BLT_TESTS_FORMAT_H + +#include +#include +#include + +namespace blt::string { + + /** + * Ensure that string str has expected length, pad after the string otherwise. + * @param str string to pad + * @param expectedLength expected length of the string. + * @return a space padded string + */ + static inline std::string postPadWithSpaces(const std::string& str, size_t expectedLength) { + auto currentSize = (int) (str.length() - 1); + if ((int) expectedLength - currentSize <= 0) + return str; + auto paddedString = str; + for (int i = 0; i < expectedLength - currentSize; i++) + paddedString += " "; + return paddedString; + } + + /** + * Ensure that string str has expected length, pad before the string otherwise. + * @param str string to pad + * @param expectedLength expected length of the string. + * @return a space padded string + */ + static inline std::string prePadWithSpaces(const std::string& str, size_t expectedLength) { + auto currentSize = str.length() - 1; + auto paddedString = std::string(); + for (int i = 0; i < expectedLength - currentSize; i++) + paddedString += " "; + paddedString += str; + return paddedString; + } + + struct TableColumn { + std::string columnName; + size_t maxColumnLength = 0; + TableColumn(std::string columnName): columnName(std::move(columnName)) {} + }; + + struct TableRow { + std::vector rowValues; + }; + + class TableFormatter { + private: + int m_columnPadding; + int m_maxColumnWidth; + std::vector columns; + std::vector rows; + + static std::string generateTopSeparator(size_t size); + std::string generateColumnHeader(); + std::string generateSeparator(size_t size); + void updateMaxColumnLengths(); + [[nodiscard]] inline size_t columnSize(const TableColumn& column) const { + return column.columnName.size() + m_columnPadding * 2; + } + public: + explicit TableFormatter(int columnPadding = 2, int maxColumnWidth = 500): + m_columnPadding(columnPadding), m_maxColumnWidth(maxColumnWidth) {} + + inline void addColumn(const TableColumn& column) { + columns.push_back(column); + } + inline void addRow(TableRow row){ + if (row.rowValues.size() > columns.size()) + throw "Cannot insert more rows than columns!\n"; + // ensure every row populates every column. This is important as the table generator assumes that all rows are complete! + if (row.rowValues.size() < columns.size()) + for (auto i = row.rowValues.size(); i < columns.size(); i++) + row.rowValues.emplace_back(" "); + rows.push_back(std::move(row)); + } + inline void addRow(const std::initializer_list& values){ + TableRow row; + for (const auto& value : values) + row.rowValues.push_back(value); + addRow(row); + } + std::vector createTable(bool top = false, bool bottom = false); + }; + +} +#endif //BLT_TESTS_FORMAT_H diff --git a/include/blt/std/string.h b/include/blt/std/string.h index 3d57408..cb3cf7e 100644 --- a/include/blt/std/string.h +++ b/include/blt/std/string.h @@ -16,37 +16,6 @@ namespace blt::string { - /** - * Ensure that string str has expected length, pad after the string otherwise. - * @param str string to pad - * @param expectedLength expected length of the string. - * @return a space padded string - */ - static inline std::string postPadWithSpaces(const std::string& str, size_t expectedLength) { - auto currentSize = (int)(str.length() - 1); - if ((int)expectedLength - currentSize <= 0) - return str; - auto paddedString = str; - for (int i = 0; i < expectedLength - currentSize; i++) - paddedString += " "; - return paddedString; - } - - /** - * Ensure that string str has expected length, pad before the string otherwise. - * @param str string to pad - * @param expectedLength expected length of the string. - * @return a space padded string - */ - static inline std::string prePadWithSpaces(const std::string& str, size_t expectedLength) { - auto currentSize = str.length() - 1; - auto paddedString = std::string(); - for (int i = 0; i < expectedLength - currentSize; i++) - paddedString += " "; - paddedString += str; - return paddedString; - } - static inline bool starts_with(const std::string& string, const std::string& search){ if (search.length() > string.length()) return false; diff --git a/src/blt/profiling/profiler.cpp b/src/blt/profiling/profiler.cpp index f6b5b60..3b05006 100644 --- a/src/blt/profiling/profiler.cpp +++ b/src/blt/profiling/profiler.cpp @@ -11,6 +11,7 @@ #include #include #include +#include namespace blt::profiling { @@ -53,18 +54,18 @@ namespace blt::profiling { } } - void printProfile(const std::string& profileName, int loggingLevel) { + void printProfileOld(const std::string& profileName, int loggingLevel) { std::vector lines; const auto& profile = profiles[profileName]; const auto& intervals = profile.intervals; const auto& points = profile.points; - + { std::string profileNameString = "Profile "; profileNameString += profileName; profileNameString += " Recorded {\n"; lines.emplace_back(profileNameString); - + for (const auto& interval : intervals) { const auto difference = interval.second.end - interval.second.start; std::string currentIntervalString = "\t"; @@ -74,7 +75,7 @@ namespace blt::profiling { currentIntervalString += "ns ("; currentIntervalString += std::to_string((double) difference / 1000000.0); currentIntervalString += "ms);\n"; - + lines.emplace_back(currentIntervalString); } lines.emplace_back("}\n"); @@ -82,6 +83,29 @@ namespace blt::profiling { print(lines, loggingLevel); } + void printProfile(const std::string& profileName, int loggingLevel) { + string::TableFormatter formatter; + formatter.addColumn({"Interval"}); + formatter.addColumn({"Time (ns)"}); + formatter.addColumn({"Time (ms)"}); + + const auto& profile = profiles[profileName]; + const auto& intervals = profile.intervals; + const auto& points = profile.points; + + for (const auto& interval : intervals) { + const auto difference = interval.second.end - interval.second.start; + formatter.addRow({interval.first, std::to_string(difference), std::to_string(difference/1000000)}); + } + + std::vector updatedLines; + const auto& lines = formatter.createTable(true, true); + for (const auto& line : lines) + updatedLines.emplace_back(line + "\n"); + + print(updatedLines, loggingLevel); + } + struct timeOrderContainer { long difference; std::string name; @@ -146,6 +170,7 @@ namespace blt::profiling { } lines.emplace_back("}\n"); } + print(lines, loggingLevel); } diff --git a/src/blt/std/format.cpp b/src/blt/std/format.cpp new file mode 100644 index 0000000..ab19072 --- /dev/null +++ b/src/blt/std/format.cpp @@ -0,0 +1,100 @@ +/* + * Created by Brett on 26/01/23. + * Licensed under GNU General Public License V3.0 + * See LICENSE file for license detail + */ +#include +#include +#include "blt/std/logging.h" + +std::string createPadding(int padAmount) { + std::string padStr; + for (int i = 0; i < padAmount; i++) + padStr += " "; + return padStr; +} + +std::vector blt::string::TableFormatter::createTable(bool top, bool bottom) { + std::vector table; + const auto& tableHeader = generateColumnHeader(); + const auto& topSeparator = generateTopSeparator(tableHeader.size()); + const auto& lineSeparator = generateSeparator(tableHeader.size()); + + if (top) + table.push_back(topSeparator); + + table.push_back(tableHeader); + table.push_back(lineSeparator); + + for (const auto& row : rows) { + std::string rowString = "|"; + for (int i = 0; i < row.rowValues.size(); i++) { + const auto& rowValue = row.rowValues[i]; + const auto& column = columns[i]; + const int spaceLeft = int(column.maxColumnLength) - int(rowValue.size()); + // we want to prefer putting the space on the right size, flooring left and ceiling right ensures this. + rowString += createPadding((int)std::floor(spaceLeft/2.0) + m_columnPadding); + rowString += rowValue; + rowString += createPadding((int)std::ceil(spaceLeft/2.0) + m_columnPadding); + rowString += "|"; + } + table.push_back(rowString); + } + + if (bottom) + table.push_back(lineSeparator); + + return table; +} + +std::string blt::string::TableFormatter::generateColumnHeader() { + updateMaxColumnLengths(); + std::string header = "|"; + + for (int i = 0; i < columns.size(); i++) { + const auto& column = columns[i]; + auto columnPaddingLength = (int(column.maxColumnLength) - int(column.columnName.size()))/2.0; + header += createPadding(int(m_columnPadding + (int)std::floor(columnPaddingLength))); + + header += column.columnName; + + header += createPadding(int(m_columnPadding + (int)std::ceil(columnPaddingLength))); + if (i < columns.size()-1) + header += "|"; + } + + header += "|"; + return header; +} + +std::string blt::string::TableFormatter::generateTopSeparator(size_t size) { + std::string wholeWidthSeparator; + for (int i = 0; i < size; i++) + wholeWidthSeparator += "-"; + return wholeWidthSeparator; +} + +std::string blt::string::TableFormatter::generateSeparator(size_t size) { + size_t nextIndex = 0; + size_t currentColumnIndex = 0; + std::string wholeWidthSeparator; + for (int i = 0; i < size; i++) { + if (i == nextIndex) { + auto currentColumnSize = columns[currentColumnIndex++].maxColumnLength + m_columnPadding*2; + nextIndex += currentColumnSize+1; + wholeWidthSeparator += "+"; + } else + wholeWidthSeparator += "-"; + } + return wholeWidthSeparator; +} + +void blt::string::TableFormatter::updateMaxColumnLengths() { + for (int i = 0; i < columns.size(); i++) { + auto& column = columns[i]; + column.maxColumnLength = column.columnName.size(); + for (const auto& row : rows) { + column.maxColumnLength = std::max(column.maxColumnLength, row.rowValues[i].size()); + } + } +} diff --git a/src/blt/std/queues.cpp b/src/blt/std/queues.cpp deleted file mode 100644 index 7d853c4..0000000 --- a/src/blt/std/queues.cpp +++ /dev/null @@ -1,10 +0,0 @@ -/* - * Created by Brett on 26/12/22. - * Licensed under GNU General Public License V3.0 - * See LICENSE file for license detail - */ -#include - -namespace blt { - -} \ No newline at end of file diff --git a/src/blt/std/random.cpp b/src/blt/std/random.cpp deleted file mode 100644 index 93d577c..0000000 --- a/src/blt/std/random.cpp +++ /dev/null @@ -1,6 +0,0 @@ -/* - * Created by Brett on 04/01/23. - * Licensed under GNU General Public License V3.0 - * See LICENSE file for license detail - */ -#include \ No newline at end of file diff --git a/src/blt/std/string.cpp b/src/blt/std/string.cpp deleted file mode 100644 index 66d8a99..0000000 --- a/src/blt/std/string.cpp +++ /dev/null @@ -1,6 +0,0 @@ -/* - * Created by Brett on 26/12/22. - * Licensed under GNU General Public License V3.0 - * See LICENSE file for license detail - */ -#include \ No newline at end of file diff --git a/src/tests/main.cpp b/src/tests/main.cpp index aef0ffd..ad603f1 100644 --- a/src/tests/main.cpp +++ b/src/tests/main.cpp @@ -5,9 +5,15 @@ #include "blt/profiling/profiler.h" #include "blt/std/logging.h" #include "blt/std/time.h" +#include "blt/std/format.h" #include #include +void print(const std::vector& vtr) { + for (const auto& line : vtr) + BLT_TRACE(line); +} + int main() { binaryTreeTest(); @@ -52,5 +58,23 @@ int main() { BLT_PRINT_PROFILE("Help", blt::logging::LOG_LEVEL::TRACE); BLT_PRINT_ORDERED("Help", blt::logging::LOG_LEVEL::TRACE); + blt::string::TableFormatter formatter; + formatter.addColumn(blt::string::TableColumn{"Test1"}); + formatter.addColumn(blt::string::TableColumn{"Test2"}); + formatter.addColumn(blt::string::TableColumn{"Test Column"}); + formatter.addColumn(blt::string::TableColumn{"Test3"}); + + formatter.addRow({"This", "This LARGE", "222", "5000"}); + formatter.addRow({"OTHER", "LARGE", "6", "1"}); + formatter.addRow({"hheee", "looo", "m8", "loser"}); + + print(formatter.createTable(true, true)); + BLT_TRACE(""); + print(formatter.createTable(false, true)); + BLT_TRACE(""); + print(formatter.createTable(true, false)); + BLT_TRACE(""); + print(formatter.createTable(false, false)); + return 0; } \ No newline at end of file