diff --git a/test/tests/Tmeta.cpp b/test/tests/Tmeta.cpp
new file mode 100644
index 0000000..3be6621
--- /dev/null
+++ b/test/tests/Tmeta.cpp
@@ -0,0 +1,174 @@
+/*!
+ * \file Tmeta.cpp
+ *
+ * Copyright (C) 2018 Christos Choutouridis
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see .
+ *
+ */
+#include
+#include
+#include
+
+namespace test_meta {
+ using namespace utl;
+ using namespace meta;
+
+ /*
+ * Test integral constant
+ */
+ // Test type_of fixture
+ template struct TestTypeOf {
+ using type = T;
+ };
+ TEST(Tmeta_integral, Integreal_type_) {
+ EXPECT_EQ(true, (std::is_same>>::value));
+ }
+ TEST(Tmeta_integral, IntegrealConstant) {
+ EXPECT_EQ(true, (std::is_same::value_type>::value));
+ EXPECT_EQ(true, (std::is_same::type::value_type>::value));
+ EXPECT_EQ(42, (integral_constant::value_type(42)));
+ EXPECT_EQ(42, (integral_constant()));
+ }
+ TEST(Tmeta_integral, BasicTypes) {
+ EXPECT_EQ(true, (std::is_same::value_type>::value));
+ EXPECT_EQ(true, bool_::value);
+ EXPECT_EQ(true, (std::is_same::value));
+ EXPECT_EQ(false, false_::value);
+ EXPECT_EQ(true, (std::is_same::value));
+ EXPECT_EQ(true, true_::value);
+ EXPECT_EQ(true, (std::is_same::value_type>::value));
+ EXPECT_EQ(42, int_<42>::value);
+
+ EXPECT_EQ(true, (std::is_same::value_type>::value));
+ EXPECT_EQ(42U, index_t_<42U>::value);
+ EXPECT_EQ(true, (std::is_same::value_type>::value));
+ EXPECT_EQ(42U, size_t_<42U>::value);
+
+ EXPECT_EQ(sizeof(int), sizeof_::value);
+ EXPECT_EQ(alignof(int), alignof_::value);
+ EXPECT_EQ(static_cast(-1), Npos::value);
+ }
+ /*
+ * Test integral constant arithmetic operations
+ */
+ TEST(Tmeta_integral, ArithmeticOperations) {
+ EXPECT_EQ (int_<42>(), inc>());
+ EXPECT_EQ (int_<42>(), dec>());
+ EXPECT_EQ (int_<42>(), (add, add, int_<2>>>()));
+ EXPECT_EQ (int_<42>(), (sub, int_<66>>()));
+ EXPECT_EQ (int_<42>(), (mult, mult, int_<2>>>()));
+ EXPECT_EQ (int_<42>(), (divide, int_<5>>()));
+ EXPECT_EQ (int_<42>(), negate>());
+ EXPECT_EQ (int_< 1>(), (modulo, int_<42>>()));
+ }
+
+ /*
+ * Test logical
+ */
+ TEST(Tmeta_logical, ComparisonOperations) {
+ EXPECT_EQ (true, (std::is_same, not_c>::value));
+ EXPECT_EQ (true, (comp_eq, int_<7>>()));
+ EXPECT_EQ (true, (comp_ne, int_<7>>()));
+ EXPECT_EQ (true, (comp_lt, int_<43>>()));
+ EXPECT_EQ (true, (comp_gt, int_<42>>()));
+ EXPECT_EQ (true, (comp_le, int_<42>>()));
+ EXPECT_EQ (true, (comp_ge, int_<42>>()));
+ }
+
+ TEST(Tmeta_logical, BitOperations) {
+ EXPECT_EQ (0x00, (bitand_, int_<0xAA>>()));
+ EXPECT_EQ (0xFF, (bitor_, int_<0xAA>>()));
+ EXPECT_EQ (0xFA, (bitxor_, int_<0xAF>>()));
+ EXPECT_EQ (0x00, (bitnot_>()));
+ //XXX: add shifts
+ }
+
+ TEST(Tmeta_logical, TypeOperations) {
+ struct Foo {};
+ struct Bar {};
+
+ EXPECT_EQ (true, (std::is_same, not_>>()));
+ EXPECT_EQ (true, (std::is_same, if_c, bool_>>()));
+ EXPECT_EQ (true, (std::is_same, if_, int_<42>, bool_>>()));
+
+ EXPECT_EQ (true, (std::is_same, or_, bool_>>()));
+ EXPECT_EQ (true, (std::is_same, or_, bool_>>()));
+ EXPECT_EQ (true, (std::is_same, and_, bool_>>()));
+ EXPECT_EQ (true, (std::is_same, and_, bool_>>()));
+
+ EXPECT_EQ (true, (same_()));
+ EXPECT_EQ (false, (same_()));
+ EXPECT_EQ (true, (not_same_()));
+ }
+
+ /*
+ * Test void
+ */
+ TEST(Tmeta_void, VoidType) {
+ struct Foo {};
+ struct Bar {};
+ EXPECT_EQ(true, (std::is_same>()));
+ }
+ /*
+ * Test invoke
+ */
+ template struct MetaFunction { using type = int; };
+ template struct MetaClass {using apply = int; };
+ TEST(Tmeta_invoke, Invoke) {
+ //EXPECT_EQ (true, (is_evaluable()));
+ }
+ /*
+ * Test typelist
+ */
+ template struct F {};
+ TEST(Tmeta_typelist, List_fold) {
+ struct X1 {};
+ struct X2 {};
+ struct X3 {};
+ struct X4 {};
+ using Q = quote;
+
+ EXPECT_EQ(true, (std::is_same, void, Q>, void>()));
+ EXPECT_EQ(true, (std::is_same, void, Q>, F>()));
+ EXPECT_EQ(true, (std::is_same, void, Q>, F, X2>>()));
+ EXPECT_EQ(true, (std::is_same, void, Q>, F, X2>, X3>>()));
+ EXPECT_EQ(true, (std::is_same, void, Q>, F, X2>, X3>, X4>>()));
+
+ //EXPECT_EQ(true, (std::is_same, void, Q>, void>()));
+ EXPECT_EQ(true, (std::is_same, void, Q>, F>()));
+ EXPECT_EQ(true, (std::is_same, void, Q>, F>>()));
+ EXPECT_EQ(true, (std::is_same, void, Q>, F>>>()));
+ EXPECT_EQ(true, (std::is_same, void, Q>, F>>>>()));
+ }
+ TEST(Tmeta_typelist, ListOperations) {
+ using l1 = typelist;
+ using l2 = typelist<>;
+ using l3 = typelist;
+ using l4 = typelist;
+ using conc = typelist;
+ using rep = typelist;
+
+ EXPECT_EQ(3, size());
+ EXPECT_EQ(true, empty());
+
+ EXPECT_EQ(true, (std::is_same>()));
+ EXPECT_EQ(true, (std::is_same, int>>()));
+ EXPECT_EQ(true, (std::is_same>()));
+ EXPECT_EQ(true, (std::is_same>()));
+ EXPECT_EQ(true, (std::is_same>>()));
+
+ EXPECT_EQ(true, (std::is_same, pop_front>()));
+ }
+}
diff --git a/test/tests/test_ostream_dev.cpp b/test/tests/test_ostream_dev.cpp
new file mode 100644
index 0000000..da9c27a
--- /dev/null
+++ b/test/tests/test_ostream_dev.cpp
@@ -0,0 +1,257 @@
+/*!
+ * \file test_ostream_dev.cpp
+ *
+ * Copyright (C) 2018 Christos Choutouridis
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+#include
+#include
+
+namespace test_ostream_dev {
+ using namespace utl;
+
+ // Device base data types
+ // MUST be DefaultConstructible, Copyable
+ using test_data_t = uint8_t;
+
+ // Test data
+ static const size_t SIZE = 10;
+
+ test_data_t Idata = 42;
+ test_data_t& IdataR = Idata;
+ test_data_t&& IdataRR = 0xAA;
+ test_data_t Ibuffer[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
+
+ // ostream device implementer (Mocks)
+ class Ostream_dev_impl : public ostream_dev {
+ friend ostream_dev;
+ public:
+ // virtual device
+ static constexpr size_t N =SIZE;
+ std::array v {}; // more than one so we can remember N-1 previous values
+ size_t c {0};
+
+ protected:
+ // ostream_dev requirements
+ size_t put_ (const test_data_t& data) {
+ v[c++] = data;
+ if (c >= N)
+ c = 0;
+ return 1;
+ }
+ size_t put_ (const test_data_t* data, size_t n) {
+ for (size_t i=0 ; i {
+ public:
+ // virtual device
+ static constexpr size_t N =SIZE;
+ std::array v {};
+ size_t c {0};
+
+ protected:
+ // ostream_dev requirements
+ size_t put_ (const test_data_t& data) {
+ v[c++] = data;
+ if (c >= N)
+ c = 0;
+ return 1;
+ }
+ size_t put_ (const test_data_t* data, size_t n) {
+ for (size_t i=0 ; i osVdev {};
+ ostream_dev *basePointer = nullptr;
+ };
+
+ //ToDo: Must add Concept test for ostream_dev
+// TEST_F(Tostream_Idev, TestConcept) {
+// EXPECT_EQ(true, Ostream_dev);
+// }
+
+ TEST_F(Tostream_Idev, Construction) {
+ EXPECT_LT(0UL, sizeof(osIdev));
+ }
+
+ TEST_F (Tostream_Idev, Api) {
+ EXPECT_EQ(1UL, osIdev.put(Idata)); // single write from var
+ EXPECT_EQ(Idata, osIdev.getLastV ());
+
+ EXPECT_EQ(1UL, osIdev.put(IdataR));// single write from lvalue ref
+ EXPECT_EQ(IdataR, osIdev.getLastV ());
+
+ EXPECT_EQ(1UL, osIdev.put(IdataRR));// single write from rvalue ref
+ EXPECT_EQ(IdataRR, osIdev.getLastV ());
+
+ EXPECT_EQ(1UL, osIdev.put(42));// single write from rvalue
+ EXPECT_EQ(42U, osIdev.getLastV ());
+
+ EXPECT_EQ(7U, osIdev.put(Ibuffer, 7)); // batch write some data
+ for (size_t i =0 ; i<7 ; ++i) {
+ EXPECT_EQ(Ibuffer[i], osIdev.v[i]);
+ }
+ EXPECT_EQ(0, osIdev.v[7]);
+
+ EXPECT_EQ(SIZE, osIdev.put(Ibuffer, SIZE)); // batch write all data
+ for (size_t i =0 ; iput(Idata);
+ EXPECT_EQ(Idata, dev.v[0]);
+
+ EXPECT_EQ(SIZE, basePointer->put(Ibuffer, SIZE)); // batch write all data
+ for (size_t i =0 ; ibegin();
+ std::fill_n(it, SIZE, Idata);
+ for (size_t i=0 ;i