diff --git a/source/simple/support/algorithm.hpp b/source/simple/support/algorithm.hpp
index 4d3640cfad8cbcf7b8a96d5ab16618fffee34827..89831203807bdac35593d84176c7a5a3bcecb3e8 100644
--- a/source/simple/support/algorithm.hpp
+++ b/source/simple/support/algorithm.hpp
@@ -1,6 +1,8 @@
 #include "algorithm/advance_vector.hpp"
 #include "algorithm/numeric.hpp"
 #include "algorithm/range_wrappers.hpp"
+#include "algorithm/set_ops.hpp"
+#include "algorithm/split.hpp"
 #include "algorithm/traits.hpp"
 #include "algorithm/utils.hpp"
 #include "algorithm/variance.hpp"
diff --git a/source/simple/support/algorithm/range_wrappers.hpp b/source/simple/support/algorithm/range_wrappers.hpp
index 15cb0b2671c5cc2d99bebfb7fc3317e72e970681..8f72213c9ba9d4b4b45db4b225d30a6aae7bed03 100644
--- a/source/simple/support/algorithm/range_wrappers.hpp
+++ b/source/simple/support/algorithm/range_wrappers.hpp
@@ -1,13 +1,24 @@
 #ifndef SIMPLE_SUPPORT_ALGORITHM_RANGE_WRAPPERS_HPP
 #define SIMPLE_SUPPORT_ALGORITHM_RANGE_WRAPPERS_HPP
 #include <algorithm>
+#include <string_view>
 
 namespace simple::support
 {
 
 	// TODO: use the adl pattern for begin and end - unqualified call that defaults to std versions, noexcept being the tricky part of course
 
-	// rangey wrappers
+
+	// TODO: check if string view has begin-end constructor(should since c++20) and replace this with alias
+	class string_view : public std::string_view
+	{
+		public:
+		using std::string_view::string_view;
+		string_view(const_iterator begin, const_iterator end)
+			: std::string_view(begin, end-begin)
+		{}
+	};
+
 
 	template <typename Range>
 	constexpr auto min_element(Range& range)
diff --git a/source/simple/support/algorithm/set_ops.hpp b/source/simple/support/algorithm/set_ops.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..e2bfc9fc670d597a00bf3879fcdbd15df5018cde
--- /dev/null
+++ b/source/simple/support/algorithm/set_ops.hpp
@@ -0,0 +1,56 @@
+#ifndef SIMPLE_SUPPORT_ALGORITHM_SET_OPS_HPP
+#define SIMPLE_SUPPORT_ALGORITHM_SET_OPS_HPP
+#include <functional> // all this for just std::less
+
+namespace simple::support
+{
+
+	namespace detail
+	{
+		template <typename MinuendIt, typename SubtrahendIt, typename Less>
+		constexpr bool not_in_set
+		(
+			SubtrahendIt& sub_begin, SubtrahendIt sub_end,
+			MinuendIt minuend,
+			Less&& less
+		)
+		{
+			while(sub_begin != sub_end)
+			{
+				// TODO: I should use invoke, but it's not constexpr, and apply(forward_as_tuple) is unreadable
+				if(less(*minuend, *sub_begin))
+					return true;
+				else if(less(*sub_begin, *minuend))
+					++sub_begin;
+				else
+				{
+					++sub_begin;
+					return false;
+				}
+			}
+			return true;
+		}
+	} // namespace detail
+
+	// cause standard version is not allowed to work in place for some reason
+	template <typename MinuendIt, typename SubtrahendIt, typename DifferenceIt, typename Less = std::less<>>
+	constexpr DifferenceIt set_difference
+	(
+		MinuendIt begin, MinuendIt end,
+		SubtrahendIt sub_begin, SubtrahendIt sub_end,
+		DifferenceIt diff,
+		Less&& less = std::less<>{}
+	)
+	{
+		while(begin != end)
+		{
+			if(detail::not_in_set(sub_begin, sub_end, begin, less))
+				*diff++ = *begin;
+			++begin;
+		}
+		return diff;
+	}
+
+} // namespace simple::support
+
+#endif /* end of include guard */
diff --git a/source/simple/support/algorithm/split.hpp b/source/simple/support/algorithm/split.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..97de62a14412c9dd6e1288652f04cec5b826b36b
--- /dev/null
+++ b/source/simple/support/algorithm/split.hpp
@@ -0,0 +1,63 @@
+#ifndef SIMPLE_SUPPORT_ALGORITHM_SPLIT_HPP
+#define SIMPLE_SUPPORT_ALGORITHM_SPLIT_HPP
+#include "traits.hpp"
+#include "../range.hpp"
+
+namespace simple::support
+{
+
+	// cause we don't get a proper standard search until c++20, and even then it depends on super experimental ranges library
+	// (how does stuff like that even get in i wonder -_-)
+	template <typename It, typename NeedleIt>
+	simple::support::range<It> search(It begin, It end, NeedleIt nbegin, NeedleIt nend)
+	{
+		while(true)
+		{
+			It found = begin;
+			NeedleIt ncurrent = nbegin;
+			do
+				if(ncurrent == nend)
+					return {begin, found};
+				else if(found == end)
+					return {end, end};
+			while(*found++ == *ncurrent++);
+			++begin;
+		}
+		return {end,end}; // unreachable
+	}
+
+	template <typename It, typename SepIt, typename OutIt>
+	auto split(It begin, It end, SepIt s_begin, SepIt s_end, OutIt out)
+	{
+		assert(s_begin != s_end); // TODO: implement a version that skips consecutive separators, and will return character by character split in this case
+		auto prev = begin;
+		auto next = end;
+		do
+		{
+			auto found = support::search(prev, end,
+				s_begin, s_end);
+			next = found.begin();
+			*out++ = {prev, next};
+			prev = found.end();
+		}
+		while(end != next);
+
+		return out;
+	}
+
+	template <typename Range, typename Separator, typename OutIt,
+		std::enable_if_t<
+			is_range_v<Range> &&
+			is_range_v<Separator>
+		>* = nullptr
+	>
+	auto split(const Range& in, const Separator& seperator, OutIt out)
+	{
+		using std::begin;
+		using std::end;
+		return split(begin(in), end(in), begin(seperator), end(seperator), out);
+	}
+
+} // namespace simple::support
+
+#endif /* end of include guard */
diff --git a/unit_tests/algorithm.cpp b/unit_tests/algorithm.cpp
index 2c4e6954a1c6c060b07a5c5750a860044c8efcff..ba779e2bd37dc641c5b13e4821ed0ff68b1cbc1c 100644
--- a/unit_tests/algorithm.cpp
+++ b/unit_tests/algorithm.cpp
@@ -1,10 +1,13 @@
+// TODO: need a test file per header and include the header first, to detect missing includes
+
 #include <cassert>
 #include <vector>
 #include <numeric>
 #include "simple/support/algorithm.hpp"
 
 
-using namespace simple::support;
+using namespace simple;
+using namespace support;
 
 void MultidimentionalIteration()
 {
@@ -218,6 +221,126 @@ void TypeTraits()
 	static_assert(is_range_v<adl_range_test::segment>);
 }
 
+void Search()
+{
+	{
+		char x[] = "aaab";
+		char y[] = "aab";
+		assert(::search(std::begin(x), std::end(x), std::begin(y), std::end(y)).begin() == x + 1);
+		assert(::search(std::begin(x), std::end(x), std::begin(y), std::end(y)).end() == std::end(x));
+		assert(*(std::end(x) - 1) == '\0');
+	}
+	{
+		char x[] = "aaab";
+		char y[] = "aba";
+		assert(search(std::begin(x), std::end(x), std::begin(y), std::end(y)).begin() == std::end(x));
+		assert(search(std::begin(x), std::end(x), std::begin(y), std::end(y)).end() == std::end(x));
+	}
+	{
+		std::array<char,4> x = {'a','a','a','b'};
+		char y[] = "aba";
+		assert(search(std::begin(x), std::end(x), std::begin(y), std::end(y)).begin() == std::end(x));
+		assert(search(std::begin(x), std::end(x), std::begin(y), std::end(y)).end() == std::end(x));
+	}
+	{
+		std::array<char,4> x = {'a','a','a','b'};
+		std::array<char,3> y = {'a','b','a'};
+		assert(search(std::begin(x), std::end(x), std::begin(y), std::end(y)).begin() == std::end(x));
+		assert(search(std::begin(x), std::end(x), std::begin(y), std::end(y)).end() == std::end(x));
+	}
+	{
+		char x[] = "aaab";
+		std::array<char,0> y{};
+		assert(search(std::begin(x), std::end(x), std::begin(y), std::end(y)).begin() == std::begin(x));
+		assert(search(std::begin(x), std::end(x), std::begin(y), std::end(y)).end() == std::begin(x));
+	}
+}
+
+auto split(std::string_view view, const std::string& separator)
+{
+	std::vector<string_view> result;
+	support::split(view, separator, std::back_inserter(result));
+	return result;
+}
+
+void Split()
+{
+	assert(( ::split("a--b--c", "--") == std::vector<string_view>{"a", "b", "c"} ));
+	assert(( ::split("a--b--c--", "--") == std::vector<string_view>{"a", "b", "c", ""} ));
+	assert(( ::split("--a--b--c", "--") == std::vector<string_view>{"", "a", "b", "c"} ));
+	assert(( ::split("--a--b--c--", "--") == std::vector<string_view>{"", "a", "b", "c", ""} ));
+	assert(( ::split("--""--""--""--""--a--b--c--", "--") == std::vector<string_view>{"", "", "", "", "", "a", "b", "c", ""} ));
+	assert(( ::split("--", "--") == std::vector<string_view>{"", ""} ));
+	assert(( ::split("", "--") == std::vector<string_view>{""} ));
+}
+
+void SetDifference()
+{
+	{
+		std::array x {1,2,2,3,4,5};
+		std::array y {2,4};
+		std::array<int, 4> z;
+		support::set_difference(std::begin(x), std::end(x), std::begin(y), std::end(y), std::begin(z));
+		assert(( z == std::array{1,2,3,5} ));
+	}
+
+	{
+		std::array x {5,4,3,2,2,1};
+		std::array y {4,2};
+		std::array<int, 4> z;
+		support::set_difference(std::begin(x), std::end(x), std::begin(y), std::end(y), std::begin(z), std::greater<>{});
+		assert(( z == std::array{5,3,2,1} ));
+	}
+
+	{
+		std::array x {1,2,2,3,4,5};
+		std::array y {2,4};
+		auto diff_end = support::set_difference(std::begin(x), std::end(x), std::begin(y), std::end(y), std::begin(x));
+		std::array diff{1,2,3,5};
+		assert( std::equal(std::begin(x), diff_end, std::begin(diff)) );
+	}
+
+	{
+		std::array x {1,2,2,3,4,5};
+		std::array<int,0> y {};
+		auto diff_end = support::set_difference(std::begin(x), std::end(x), std::begin(y), std::end(y), std::begin(x));
+		std::array diff{1,2,2,3,4,5};
+		assert( std::equal(std::begin(x), diff_end, std::begin(diff)) );
+	}
+
+	{
+		std::array<int,0> x {};
+		std::array y {1,2,3};
+		auto diff_end = support::set_difference(std::begin(x), std::end(x), std::begin(y), std::end(y), std::begin(x));
+		std::array<int,0> diff{};
+		assert( std::equal(std::begin(x), diff_end, std::begin(diff)) );
+	}
+
+	{
+		std::array x {1,2,3};
+		std::array y {1,2,3};
+		auto diff_end = support::set_difference(std::begin(x), std::end(x), std::begin(y), std::end(y), std::begin(x));
+		std::array<int,0> diff{};
+		assert( std::equal(std::begin(x), diff_end, std::begin(diff)) );
+	}
+
+	{
+		std::array x {1,2,3};
+		std::array y {1,2,3,4,5,6};
+		auto diff_end = support::set_difference(std::begin(x), std::end(x), std::begin(y), std::end(y), std::begin(x));
+		std::array<int,0> diff{};
+		assert( std::equal(std::begin(x), diff_end, std::begin(diff)) );
+	}
+
+	{
+		std::array x {12,12,12,12,12,12,12};
+		std::array y {12,12,12,12,12,12};
+		auto diff_end = support::set_difference(std::begin(x), std::end(x), std::begin(y), std::end(y), std::begin(x));
+		std::array diff{12};
+		assert( std::equal(std::begin(x), diff_end, std::begin(diff)) );
+	}
+}
+
 int main()
 {
 	MultidimentionalIteration();
@@ -225,6 +348,9 @@ int main()
 	IteratorRange();
 	Variance();
 	TypeTraits();
+	Search();
+	Split();
+	SetDifference();
 	static_assert(Constexprness());
 	return 0;
 }