diff --git a/alib2/src/std/istream.cpp b/alib2/src/std/istream.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f12a3dceb8d454ea662f3a13b59140ba5661a09d
--- /dev/null
+++ b/alib2/src/std/istream.cpp
@@ -0,0 +1,27 @@
+#include "istream.h"
+
+std::istream& oprr(std::istream& in, const std::string& str, bool start) {
+  if(str.size() == 0) return in;
+  char c_str = str[0];
+  char c_in  = in.peek();
+  in.get();
+  if(in.good()) {
+    if(start && (c_in == ' ' || c_in == '\n' || c_in == '\t')) {
+      oprr(in, str, start);
+    } else if(c_str == c_in) {
+      oprr(in, str.substr(1), false);
+    } else {
+      in.clear(std::ios::failbit);
+    }
+  }
+  if(in.fail()) {
+    in.clear();
+    in.putback(c_in);
+    in.clear(std::ios::failbit);
+  }
+  return in;
+}
+
+std::istream& operator>>(std::istream& in, const std::string& str) {
+  return oprr(in, str, true);
+}
\ No newline at end of file
diff --git a/alib2/src/std/istream.h b/alib2/src/std/istream.h
new file mode 100644
index 0000000000000000000000000000000000000000..3d5167191f0463ca0ca6b4760e7915b0b166f1f1
--- /dev/null
+++ b/alib2/src/std/istream.h
@@ -0,0 +1,9 @@
+#ifndef ISTREAM_H_
+#define ISTREAM_H_
+
+#include <iostream>
+#include <string>
+
+std::istream& operator>>(std::istream& in, const std::string& str);
+
+#endif
\ No newline at end of file
diff --git a/alib2/test-src/std/StdTest.cpp b/alib2/test-src/std/StdTest.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..fd61201ee10cd92e0289dca02a5a1365785e6da6
--- /dev/null
+++ b/alib2/test-src/std/StdTest.cpp
@@ -0,0 +1,94 @@
+#include "StdTest.h"
+#include "std/variant.hpp"
+#include <set>
+
+CPPUNIT_TEST_SUITE_REGISTRATION( StdTest );
+
+void StdTest::setUp() {
+}
+
+void StdTest::tearDown() {
+}
+ 
+void StdTest::testIsBaseOf() {
+	CPPUNIT_ASSERT( ( std::is_base_of_any<int, int, std::string, StdTest::test>::value ) == true );
+	CPPUNIT_ASSERT( ( std::is_base_of<int, int>::value ) == true );
+	CPPUNIT_ASSERT( ( std::is_base_of<int, std::string>::value ) == false );
+	CPPUNIT_ASSERT( ( std::is_base_of<int, StdTest::test>::value ) == false );
+}
+
+void StdTest::testVariant() {
+	std::variant<int, std::string, StdTest::test> d;
+ 
+	d.set<int>(10);
+	CPPUNIT_ASSERT( d.is<int>() );
+	CPPUNIT_ASSERT( d.get<int>() == 10 );
+	
+	std::string str = "abcde";
+	d.set<std::string>(str);
+	CPPUNIT_ASSERT( d.is<std::string>() );
+	CPPUNIT_ASSERT( d.get<std::string>() == str );
+	
+	d.set<StdTest::test>(StdTest::test());
+	*(d.get<StdTest::test>().holder) = 42;
+	
+	StdTest::test tmp;
+	*(tmp.holder) = 42;
+	CPPUNIT_ASSERT( d.is<StdTest::test>() );
+	CPPUNIT_ASSERT( d.get<StdTest::test>() == tmp );
+	
+	std::variant<int, std::string, StdTest::test> e(d);
+	CPPUNIT_ASSERT( e.get<StdTest::test>() == tmp );
+ 
+	*(e.get<StdTest::test>().holder) = 43;
+ 
+	CPPUNIT_ASSERT( (d < e) == true );
+	CPPUNIT_ASSERT( (e < d) == false );
+	
+	CPPUNIT_ASSERT( (e == d) == false );
+	
+	d = std::variant<int, std::string, StdTest::test>();
+	d = e;
+
+	CPPUNIT_ASSERT( *(d.get<StdTest::test>().holder) == 43 );
+	
+	CPPUNIT_ASSERT( (d < e) == false );
+	CPPUNIT_ASSERT( (e < d) == false );
+	
+	CPPUNIT_ASSERT( (e == d) == true );
+}
+
+void StdTest::testVariantSet() {
+	StdTest::test tmp;
+	*(tmp.holder) = 42;
+	
+	std::string str = "abcde";
+	
+	std::variant<int, std::string, StdTest::test> d;
+	d.set<StdTest::test>(StdTest::test());
+	*(d.get<StdTest::test>().holder) = 42;
+	std::variant<int, std::string, StdTest::test> e(d);
+	
+	std::variant<int, std::string, StdTest::test> f;
+	f.set<int>(5);
+	
+	std::variant<int, std::string, StdTest::test> g;
+	g.set<std::string>(str);
+	
+	std::set<std::variant<int, std::string, StdTest::test>> testSet;
+	testSet.insert(d);
+	testSet.insert(e);
+	testSet.insert(f);
+	testSet.insert(g);
+	
+	CPPUNIT_ASSERT( testSet.size() == 3 );
+	
+	for(std::set<std::variant<int, std::string, StdTest::test>>::const_iterator iter = testSet.begin(); iter != testSet.end(); iter++) {
+		if(iter->is<int>())
+			CPPUNIT_ASSERT( iter->get<int>() == 5);
+		if(iter->is<std::string>())
+			CPPUNIT_ASSERT( iter->get<std::string>() == str );
+		if(iter->is<StdTest::test>())
+			CPPUNIT_ASSERT( iter->get<StdTest::test>() == tmp );
+	}
+}
diff --git a/alib2/test-src/std/StdTest.h b/alib2/test-src/std/StdTest.h
new file mode 100644
index 0000000000000000000000000000000000000000..ae59094523d1c9545a207db67aebe1c1a1d6aaf2
--- /dev/null
+++ b/alib2/test-src/std/StdTest.h
@@ -0,0 +1,61 @@
+#ifndef VARIANT_TEST_H_
+#define VARIANT_TEST_H_
+
+#include <cppunit/extensions/HelperMacros.h>
+
+class StdTest : public CppUnit::TestFixture
+{
+  CPPUNIT_TEST_SUITE( StdTest );
+  CPPUNIT_TEST( testIsBaseOf );
+  CPPUNIT_TEST( testVariant );
+  CPPUNIT_TEST( testVariantSet );
+  CPPUNIT_TEST_SUITE_END();
+    
+struct test {
+	int * holder;
+
+	test() {
+		//std::cout << "test()" << std::endl;
+		holder = new int();
+	}
+
+	test(test&& old) : holder(nullptr) {
+		//std::cout << "test(test&&)" << std::endl;
+		std::swap(holder,old.holder);
+	}
+
+	test(const test& old) {
+		  //std::cout << "test(const test&)" << std::endl;
+		  holder = new int(*old.holder);
+	}
+
+	~test()
+	{
+		//std::cout << "~test()" << std::endl;
+		delete holder;
+	}
+
+	bool operator<(const test& other) const {
+		return *(this->holder) < *(other.holder);
+	}
+
+	bool operator==(const test& other) const {
+		return *(this->holder) == *(other.holder);
+	}
+
+	friend std::ostream& operator<<(std::ostream& out, const test& other) {
+		out << *(other.holder);
+		return out;
+	}
+};
+
+public:
+  void setUp();
+  void tearDown();
+
+  void testIsBaseOf();
+  void testVariant();
+  void testVariantSet();
+};
+
+#endif  // VARIANT_TEST_H_
\ No newline at end of file