diff --git a/library/include/binary/algorithm/experimental.hpp b/library/include/binary/algorithm/experimental.hpp index bcbc1fb..c68f765 100644 --- a/library/include/binary/algorithm/experimental.hpp +++ b/library/include/binary/algorithm/experimental.hpp @@ -74,7 +74,7 @@ namespace binary::algorithm::tree::v1_shared_ptr { void insert_node(pointer_type node); template - requires std::constructible_from + requires std::constructible_from void insert_node(Args &&...args) { insert_node(std::make_shared(std::forward(args)...)); } diff --git a/library/include/binary/algorithm/interval_tree.hpp b/library/include/binary/algorithm/interval_tree.hpp index 2f58130..731d367 100644 --- a/library/include/binary/algorithm/interval_tree.hpp +++ b/library/include/binary/algorithm/interval_tree.hpp @@ -29,21 +29,22 @@ namespace binary::algorithm::tree { /** Interval Node and Interval Tree */ template - concept IntervalConcept = requires(Interval const &interval) { - requires std::semiregular; - requires std::movable; - requires std::same_as; - interval.low <= interval.high; - typename Interval::key_type; - }; + concept IntervalConcept + = requires(Interval const &interval) { + requires std::semiregular; + requires std::movable; + requires std::same_as; + interval.low <= interval.high; + typename Interval::key_type; + }; template concept IntervalNodeConcept = requires(Node &node) { - requires NodeConcept; - typename Node::interval_type; - node.max; - node.interval; - }; + requires NodeConcept; + typename Node::interval_type; + node.max; + node.interval; + }; /** Interval Tree node * @@ -64,7 +65,7 @@ namespace binary::algorithm::tree { constexpr IntervalNode &operator=(IntervalNode &&other) noexcept = default; template - requires std::constructible_from + requires std::constructible_from explicit constexpr IntervalNode(Arg &&...args) : interval{std::forward(args)...}, max{interval.high}, key{interval.low} {} @@ -153,7 +154,7 @@ namespace binary::algorithm::tree { -> std::optional; template - requires binary::concepts::ArgsConstructible + requires binary::concepts::ArgsConstructible [[nodiscard]] auto find_overlap(Args &&...args) const -> std::optional { return find_overlap(interval_type{std::forward(args)...}); } @@ -162,7 +163,7 @@ namespace binary::algorithm::tree { -> std::vector; template - requires binary::concepts::ArgsConstructible + requires binary::concepts::ArgsConstructible [[nodiscard]] auto find_overlaps(Args &&...args) const -> std::vector { return find_overlaps(interval_type{std::forward(args)...}); } diff --git a/library/include/binary/algorithm/rb_tree.hpp b/library/include/binary/algorithm/rb_tree.hpp index 12b0c93..c39e024 100644 --- a/library/include/binary/algorithm/rb_tree.hpp +++ b/library/include/binary/algorithm/rb_tree.hpp @@ -22,19 +22,19 @@ namespace binary::algorithm::tree { template concept NodeConcept = requires(Node &node) { - requires std::movable && std::default_initializable; - typename Node::key_type; - typename Node::pointer; - typename Node::reference_pointer; - typename Node::raw_pointer; - node.key; - node.left; - node.right; - node.parent; - node.color_; - node.is_black(); - node.is_red(); - }; + requires std::movable && std::default_initializable; + typename Node::key_type; + typename Node::pointer; + typename Node::reference_pointer; + typename Node::raw_pointer; + node.key; + node.left; + node.right; + node.parent; + node.color_; + node.is_black(); + node.is_red(); + }; enum class Color { Red, Black }; @@ -109,7 +109,7 @@ namespace binary::algorithm::tree { virtual ~RbTree() = default; template - requires std::constructible_from> + requires std::constructible_from> void insert_node(R &&range) { for (auto &&item : range) { insert_node(std::forward(item)); @@ -143,7 +143,7 @@ namespace binary::algorithm::tree { [[maybe_unused]] void insert_node(pointer node); template - requires std::constructible_from + requires std::constructible_from void insert_node(Args &&...args) { insert_node(std::make_unique(std::forward(args)...)); } diff --git a/library/include/binary/concepts.hpp b/library/include/binary/concepts.hpp index c432878..b896b2f 100644 --- a/library/include/binary/concepts.hpp +++ b/library/include/binary/concepts.hpp @@ -16,7 +16,7 @@ namespace binary::concepts { template concept ArgsConstructible - = std::constructible_from &&(!IsAnyOf...>); + = std::constructible_from && (!IsAnyOf...>); } // namespace binary::concepts diff --git a/library/include/binary/parser/vcf.hpp b/library/include/binary/parser/vcf.hpp index 385e99d..45196a4 100644 --- a/library/include/binary/parser/vcf.hpp +++ b/library/include/binary/parser/vcf.hpp @@ -73,7 +73,7 @@ namespace binary::parser::vcf { constexpr int BINARY_BCF_HT_LONG = (BINARY_BCF_HT_INT | 0x100); template - requires binary::concepts::IsAnyOf + requires binary::concepts::IsAnyOf struct InfoGetter { Datatype* data{nullptr}; int32_t count{}; @@ -162,20 +162,20 @@ namespace binary::parser::vcf { template concept InfoFieldConcept = requires(T t) { - requires std::semiregular; - requires std::movable; - requires std::derived_from; - t.update(std::shared_ptr{}); - std::cout << t; - }; + requires std::semiregular; + requires std::movable; + requires std::derived_from; + t.update(std::shared_ptr{}); + std::cout << t; + }; template struct InfoFieldFactory : public details::BaseInfoField { std::tuple::result_type())...> data_tuple{}; std::array keys_array{}; template - requires(std::convertible_to&&...) explicit InfoFieldFactory(U... args) - : keys_array{args...} { + requires(std::convertible_to && ...) + explicit InfoFieldFactory(U... args) : keys_array{args...} { static_assert(sizeof...(T) == sizeof...(U), "Number of keys and values do not match"); } InfoFieldFactory(InfoFieldFactory const&) = default; @@ -306,14 +306,14 @@ namespace binary::parser::vcf { template concept RecordConcept = requires(T record) { - requires std::semiregular; - requires std::movable; - record.chrom; - record.pos; - record.rlen; - record.info; - std::cout << record; - }; + requires std::semiregular; + requires std::movable; + record.chrom; + record.pos; + record.rlen; + record.info; + std::cout << record; + }; template class VcfRanges { public: diff --git a/library/include/binary/utils.hpp b/library/include/binary/utils.hpp index a73f284..61c162a 100644 --- a/library/include/binary/utils.hpp +++ b/library/include/binary/utils.hpp @@ -15,7 +15,7 @@ namespace binary::utils { // TODO: use binary search if range is sorted template - requires std::equality_comparable_with, Value> + requires std::equality_comparable_with, Value> auto index(Container const& container, Value&& value) -> std::size_t { auto it = std::ranges::find(container, std::forward(value)); if (it == std::ranges::end(container)) { @@ -39,7 +39,7 @@ namespace binary::utils { } template - requires std::convertible_to, std::string> + requires std::convertible_to, std::string> void merge_files(StringRange&& files, std::string_view output_file, std::string_view header = "", bool is_deleted = true, bool is_skipped_header = true) { auto output = std::ofstream(output_file.data()); @@ -72,6 +72,19 @@ namespace binary::utils { [[maybe_unused]] inline void set_trace() { spdlog::set_level(spdlog::level::trace); } [[maybe_unused]] inline void set_info() { spdlog::set_level(spdlog::level::info); } + // trim from left + inline constexpr auto trim_front = std::ranges::views::drop_while(::isspace); + + inline constexpr auto trim_back = std::ranges::views::reverse + | std::ranges::views::drop_while(::isspace) + | std::ranges::views::reverse; + + inline constexpr auto trim = trim_front | trim_back; + + auto split_str(std::string_view str, char delim) -> std::vector; + + std::string trim_str(std::string_view str); + } // namespace binary::utils #endif // BINARY_LIBRARY_INCLUDE_BINARY_UTLS_HPP_ diff --git a/library/source/utils.cpp b/library/source/utils.cpp index 5c38cf3..5e9647a 100644 --- a/library/source/utils.cpp +++ b/library/source/utils.cpp @@ -20,4 +20,19 @@ namespace binary::utils { return std::filesystem::exists(file_path); } + std::string trim_str(std::string_view str) { + auto temp = str | trim; + return {temp.begin(), temp.end()}; + } + + auto split_str(std::string_view str, char delim) -> std::vector { + auto temp_view = str | std::ranges::views::split(delim); + auto result = std::vector{}; + + for (auto const& sub_str : temp_view) { + result.emplace_back(sub_str.begin(), sub_str.end()); + } + return result; + } + } // namespace binary::utils \ No newline at end of file diff --git a/standalone/sv2nl/include/writer.hpp b/standalone/sv2nl/include/writer.hpp index 2c8e746..ffe9716 100644 --- a/standalone/sv2nl/include/writer.hpp +++ b/standalone/sv2nl/include/writer.hpp @@ -25,7 +25,7 @@ namespace sv2nl { } template - requires std::same_as, Sv2nlVcfRecord> + requires std::same_as, Sv2nlVcfRecord> void write(Sv2nlRecordRange&& records) { if (records.size() < 2) return; auto key_line = format_keys(records[0]); @@ -38,7 +38,7 @@ namespace sv2nl { } template - requires std::same_as, Sv2nlVcfRecord> + requires std::same_as, Sv2nlVcfRecord> void write_trans(Sv2nlRecordRange&& records) { if (records.size() < 2) return; auto key_line = format_keys(records[0]); diff --git a/test/source/test_utils/test_utils.cpp b/test/source/test_utils/test_utils.cpp index 431b423..d583db9 100644 --- a/test/source/test_utils/test_utils.cpp +++ b/test/source/test_utils/test_utils.cpp @@ -87,4 +87,28 @@ TEST_SUITE("test binary utils") { std::tuple t1{1, "test", 3.0}; CHECK_NOTHROW(binary::utils::print_tuple(t1)); } + + TEST_CASE("test trim view") { + using namespace binary::utils; + + std::string_view str = " test "; + auto temp = trim_str(str); + CHECK_EQ(temp, "test"); + } + + TEST_CASE("test split string") { + using namespace binary::utils; + + std::string_view str = "test1,test2,test3"; + auto temp = split_str(str, ','); + CHECK_EQ(temp.size(), 3); + CHECK_EQ(temp[0], "test1"); + CHECK_EQ(temp[1], "test2"); + CHECK_EQ(temp[2], "test3"); + + std::string_view str2 = " test1 , test2 , test3 "; + auto temp2 = split_str(str2, ','); + CHECK_EQ(temp2.size(), 3); + CHECK_EQ(temp2[0], " test1 "); + } } \ No newline at end of file