diff --git a/README.md b/README.md
index b6cf080022172f26dce69c6fff71d0eea00ca543..13c9e78a693475e8ad68c62d578a3e5f74caea3f 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,6 @@
 # rlib
 
 [![CodeFactor](https://www.codefactor.io/repository/github/recolic/rlib/badge/master)](https://www.codefactor.io/repository/github/recolic/rlib/overview/master)
-
 ![AWS CodeBuild](https://codebuild.us-west-1.amazonaws.com/badges?uuid=eyJlbmNyeXB0ZWREYXRhIjoiVUEvK3oxVFAzMlZuZkJlSFE1L1VWSU9IWDBmK0ZpRGZ2clArTDE2UTk4QUZNS1RLUEp2K0lVaVBmNmZjWHNpOXZpRktlOU5RV3k0TjNWcHFKVmVwelJFPSIsIml2UGFyYW1ldGVyU3BlYyI6IllnZUwzWndPSEN4NTFPeGoiLCJtYXRlcmlhbFNldFNlcmlhbCI6MX0%3D&branch=master)
 
 Here is recolic's private library...
diff --git a/c-with-class.h b/c-with-class.h
index da40c96fbf7183a2024d0c32f70e0666f7cdb455..4a45bc53417d1e0f300820e875c1164f0ad8a2a6 100644
--- a/c-with-class.h
+++ b/c-with-class.h
@@ -14,9 +14,9 @@
 #define RCPP_PCALL(p_objectname,i_funcname, ...) p_objectname->i_funcname(p_objectname, ##__VA_ARGS__)
 
 #define RCPP_CLASS_DECL(class_name) struct class_name;
-#define RCPP_CLASS_METHOD_DECL_1(class_name, method_name, return_type, ...) typedef return_type (* class_name##method_name##_rcpp_t)(struct class_name *this, ##__VA_ARGS__); //VAARGS is `int arg1, float arg2, ...`
+#define RCPP_CLASS_METHOD_EXTERN_DECL(class_name, method_name, return_type, ...) typedef return_type (* class_name##method_name##_rcpp_t)(struct class_name *this, ##__VA_ARGS__); //VAARGS is `int arg1, float arg2, ...`
 #define RCPP_CLASS_BEGIN(class_name) struct class_name {
-#define RCPP_CLASS_METHOD_DECL_2(class_name, method_name) RCPP_CLASS_MEMBER_DECL(class_name##method_name##_rcpp_t, method_name)
+#define RCPP_CLASS_METHOD_DECL(class_name, method_name, ...) RCPP_CLASS_MEMBER_DECL(class_name##method_name##_rcpp_t, method_name)
 #define RCPP_CLASS_MEMBER_DECL(type, name) type name;
 #define RCPP_CLASS_END() };
 #define RCPP_CLASS_METHOD_IMPL(class_name, method_name, return_type, ...) return_type class_name##method_name##_rcpp_impl(struct class_name *this, ##__VA_ARGS__) //VAARGS is `int arg1, float arg2, ...`
diff --git a/functional.hpp b/functional.hpp
index 17ca11dd9c7bbc81df90fa5454aa2c603d335627..c14bc9b603a1e89091bb05cabad97dff15669688 100644
--- a/functional.hpp
+++ b/functional.hpp
@@ -26,9 +26,10 @@ namespace rlib {
             using return_type = typename std::invoke_result<Func, Args ...>::type;
             auto operator ()(size_t count, Func f, Args ... args) {
                 std::list<return_type> ret;
+                if(count == 0) return ret;
                 for(size_t cter = 0; cter < count; ++cter)
                     ret.push_back(std::move(f(std::forward<Args>(args) ...)));
-                return std::move(ret);
+                return ret;
             }
         };
 
@@ -55,6 +56,9 @@ namespace rlib {
         static_assert(std::is_same<return_type, return_type2>::value);
         static_assert(std::is_same<return_type, return_type3>::value);
 
+        if(count == 0)
+            throw std::invalid_argument("Can not repeat for zero times.");
+
         return std::bind(impl::repeated_func<Func, Args ...>(), count, std::forward<Func>(f), std::forward<Args>(args) ...);
     }
     template <class Func, typename... Args>
diff --git a/stdio.hpp b/stdio.hpp
index fe4f69789e382605ed72cfaab385e75a0f6a9875..fe1eed8678dfe562a951363842ee99658b0ea22f 100644
--- a/stdio.hpp
+++ b/stdio.hpp
@@ -15,6 +15,7 @@
 #include <string>
 #include <iostream>
 #include <rlib/string.hpp> // format_string
+#include <type_traits>
 
 #if RLIB_OS_ID == OS_WINDOWS
 #define RLIB_IMPL_ENDLINE "\r\n"
@@ -24,6 +25,23 @@
 #define RLIB_IMPL_ENDLINE "\n"
 #endif
 
+namespace rlib {
+    namespace impl {
+        template <typename T>
+        struct print_wrapper {
+            print_wrapper() = delete;
+            print_wrapper(const T &dat)
+                : wrapper(dat) {}
+
+            const T &wrapper;
+
+            friend std::ostream & operator<< (std::ostream &os, print_wrapper<T> p) {
+                return os << p.wrapper;
+            }
+        };
+    }
+}
+
 namespace rlib {
 // print to custom stream
     template <typename PrintFinalT>
@@ -55,16 +73,13 @@ namespace rlib {
         return std::move(line);
     }
 
-// print to stdout
-    template <typename PrintFinalT>
-    void print(PrintFinalT reqArg);
-    template <typename Required, typename... Optional>
-    void print(Required reqArgs, Optional... optiArgs);
-    template <typename... Optional>
-    void println(Optional... optiArgs);
+    // default for std::cout
+    template <typename... Args>
+    void println(Args... args);
     template <>
     void println();
-
+    template <typename... Args>
+    void print(Args... args);
     template <typename Iterable, typename Printable>
     void print_iter(Iterable arg, Printable spliter);
     template <typename Iterable, typename Printable>
@@ -73,12 +88,13 @@ namespace rlib {
     void print_iter(Iterable arg);
     template <typename Iterable>
     void println_iter(Iterable arg);
-
     template <typename... Args>
     size_t printf(const std::string &fmt, Args... args);
     template <typename... Args>
     size_t printfln(const std::string &fmt, Args... args);
 
+    // implementations below --------------------------------
+
     namespace impl {
 #if RLIB_CXX_STD < 2017
         extern bool enable_endl_flush;
@@ -103,70 +119,7 @@ namespace rlib {
         return os;
     }
 
-    template <typename PrintFinalT>
-    void print(PrintFinalT reqArg)
-    {
-        std::cout << reqArg;
-    }
-    template <typename Required, typename... Optional>
-    void print(Required reqArgs, Optional... optiArgs)
-    {
-        std::cout << reqArgs << ' ';
-        print(optiArgs ...);
-    }
-    template <typename... Optional>
-    void println(Optional... optiArgs)
-    {
-        print(optiArgs ...);
-        println();
-    }
-    template <> 
-    inline void println()
-    {
-        std::cout << rlib::endl;
-    }
-
-    template <typename Iterable, typename Printable>
-    void print_iter(Iterable arg, Printable spliter)
-    {
-        for(const auto & i : arg)
-            std::cout << i << spliter;
-    }
-    template <typename Iterable, typename Printable>
-    void println_iter(Iterable arg, Printable spliter)
-    {
-        print_iter(arg, spliter);
-        std::cout << rlib::endl;
-    }
-    template <typename Iterable>
-    void print_iter(Iterable arg)
-    {
-        for(const auto & i : arg)
-            std::cout << i << ' ';
-    }
-    template <typename Iterable>
-    void println_iter(Iterable arg)
-    {
-        print_iter(arg);
-        std::cout << rlib::endl;
-    }
-
-    template <typename... Args>
-    size_t printf(const std::string &fmt, Args... args)
-    {
-        std::string to_print = impl::format_string(fmt, args...); 
-        std::cout << to_print;
-        return to_print.size();
-    }
-    template <typename... Args>
-    size_t printfln(const std::string &fmt, Args... args)
-    {
-        size_t len = rlib::printf(fmt, args...);
-        std::cout << rlib::endl;
-        return len + 1;
-    }
-
-// With custom os
+    // With custom os
     template <typename PrintFinalT>
     void print(std::ostream &os, PrintFinalT reqArg)
     {
@@ -182,7 +135,7 @@ namespace rlib {
     void println(std::ostream &os, Optional... optiArgs)
     {
         print(os, optiArgs ...);
-        println();
+        println(os);
     }
     template <> 
     inline void println(std::ostream &os)
@@ -200,35 +153,91 @@ namespace rlib {
     void println_iter(std::ostream &os, Iterable arg, Printable spliter)
     {
         print_iter(os, arg, spliter);
-        os << rlib::endl;
+        println(os);
     }
     template <typename Iterable>
     void print_iter(std::ostream &os, Iterable arg)
     {
-        for(const auto & i : arg)
-            os << i << ' ';
+        print_iter(os, arg, ' ');
     }
     template <typename Iterable>
     void println_iter(std::ostream &os, Iterable arg)
     {
-        print_iter(os, arg);
-        os << rlib::endl;
+        println_iter(os, arg, ' ');
     }
 
     template <typename... Args>
     size_t printf(std::ostream &os, const std::string &fmt, Args... args)
     {
-        std::string to_print = format_string(fmt, args...); 
-        os << to_print;
+        std::string to_print = impl::format_string(fmt, args...); 
+        print(os, to_print);
         return to_print.size();
     }
     template <typename... Args>
     size_t printfln(std::ostream &os, const std::string &fmt, Args... args)
     {
-        size_t len = rlib::printf(fmt, args...);
-        os << rlib::endl;
+        size_t len = printf(os, fmt, args...);
+        println(os);
         return len + 1;
     }
+
+
+
+    // default for std::cout
+    template <typename... Args>
+    void println(Args... args) {
+        return println(std::cout, std::forward<Args>(args) ...);
+    }
+    template <>
+    void println() {
+        return println(std::cout);
+    }
+    template <typename... Args>
+    void print(Args... args) {
+        return print(std::cout, std::forward<Args>(args) ...);
+    }
+    template <typename Iterable, typename Printable>
+    void print_iter(Iterable arg, Printable spliter) {
+        return print_iter(std::cout, std::forward<Iterable>(arg), spliter);
+    }
+    template <typename Iterable, typename Printable>
+    void println_iter(Iterable arg, Printable spliter) {
+        return println_iter(std::cout, std::forward<Iterable>(arg), spliter);
+    }
+    template <typename Iterable>
+    void print_iter(Iterable arg) {
+        return print_iter(std::cout, std::forward<Iterable>(arg));
+    }
+    template <typename Iterable>
+    void println_iter(Iterable arg) {
+        return println_iter(std::cout, std::forward<Iterable>(arg));
+    }
+    template <typename... Args>
+    size_t printf(const std::string &fmt, Args... args) {
+        return printf(std::cout, fmt, std::forward<Args>(args) ...);
+    }
+    template <typename... Args>
+    size_t printfln(const std::string &fmt, Args... args) {
+        return printfln(std::cout, fmt, std::forward<Args>(args) ...);
+    }
+
+
+    // If the stream is stringstream or ostringstream,
+    //   it will fails to match print(ostream &, args...),
+    //   and match print(args ...). It leads to an error.
+    // Here's the fallback on such sucking substitution error.
+    template <typename StreamType, typename... Args>
+    void println(StreamType &os, Args... args) {
+        using ostream_or_data = typename std::conditional<std::is_base_of<std::ostream, StreamType>::value, 
+            std::ostream &, impl::print_wrapper<StreamType>>::type;
+        return println(static_cast<ostream_or_data>(os), std::forward<Args>(args) ...);
+    }
+    template <typename StreamType, typename... Args>
+    void print(StreamType &os, Args... args) {
+        using ostream_or_data = typename std::conditional<std::is_base_of<std::ostream, StreamType>::value, 
+            std::ostream &, impl::print_wrapper<StreamType>>::type;
+        return print(static_cast<ostream_or_data>(os), std::forward<Args>(args) ...);
+    }
 }
 
 
diff --git a/test/Makefile b/test/Makefile
index 4eb71319bfb2bd0c862a9fe626c944d3d8ac2b5b..a81d86444a9921db0ae3e5244fe8c59c8f4a1ea0 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -16,10 +16,13 @@
 # 	os          rlib/sys/os.hpp
 # 	require     rlib/require/*.hpp
 
+# Test dependency:
+# string ---> common 
+
 MODULES=string meta trait stdio sio scope_guard
 
-EXTRA_FLAGS ?=
-CXXFLAGS=-I. $(EXTRA_FLAGS)
+XTRA_FLAGS ?=
+CXXFLAGS=-I. -I../.. $(XTRA_FLAGS)
 STD ?= 14
 FLAGS11=-std=c++11 rlib/libr.a
 FLAGS14=-std=c++14 rlib/libr.a
@@ -37,7 +40,11 @@ endif
 
 POSTFIX=$(STD)_$(CXX)
 
-all: string
+all: string common
+
+common:
+	$(CXX) $(CXXFLAGS) src/common.cc $(CXXFLAGS) -o src/common_$(POSTFIX).out
+	src/common_$(POSTFIX).out
 
 string:
 	$(CXX) $(CXXFLAGS) src/string.cc $(CXXFLAGS) -o src/string_$(POSTFIX).out
diff --git a/test/src/call.cc b/test/src/call.cc
deleted file mode 100644
index 67c5ab5a319fe62ee7c6178a02b19fd610f9da21..0000000000000000000000000000000000000000
--- a/test/src/call.cc
+++ /dev/null
@@ -1,17 +0,0 @@
-#include <rlib/traits.hpp>
-
-using namespace rlib;
-
-void f(int);
-
-class c{
-public:
-    auto operator()(int a){
-        return a+1;
-    }
-};
-
-int main(){
-    static_assert(is_callable<decltype(f)>(), "a");
-    static_assert(is_callable<c>(), "b");
-}
diff --git a/test/src/cclass.c b/test/src/cclass.c
index 1c0e8cee8994956705c669ec6ed561ed4469355a..80c61df3a7719ff0229c393a9e51148ff871829c 100644
--- a/test/src/cclass.c
+++ b/test/src/cclass.c
@@ -1,36 +1,61 @@
 #include <rlib/c-with-class.h>
 #include <stdio.h>
+#include <stdlib.h>
+
+typedef int element_type;
 
 RCPP_CLASS_DECL(vector)
-RCPP_CLASS_METHOD_DECL_1(vector, push_back, void, int)
-RCPP_CLASS_METHOD_DECL_1(vector, at, int, int)
+RCPP_CLASS_METHOD_EXTERN_DECL(vector, push_back, void, element_type)
+RCPP_CLASS_METHOD_EXTERN_DECL(vector, at, element_type, int)
 
 RCPP_CLASS_BEGIN(vector)
-RCPP_CLASS_METHOD_DECL_2(vector, push_back)
-RCPP_CLASS_METHOD_DECL_2(vector, at)
+RCPP_CLASS_METHOD_DECL(vector, push_back, void, element_type)
+RCPP_CLASS_METHOD_DECL(vector, at, element_type, int)
+RCPP_CLASS_MEMBER_DECL(element_type *, data)
+RCPP_CLASS_MEMBER_DECL(int, m_size)
+RCPP_CLASS_MEMBER_DECL(int, m_cap)
 RCPP_CLASS_END()
 
-RCPP_CLASS_METHOD_IMPL(vector, push_back, void, int data) {
-    printf("pushing back %d\n", data);
+RCPP_CLASS_METHOD_IMPL(vector, push_back, void, element_type data) {
+    if(this->m_size == this->m_cap) {
+        this->m_cap += 1;
+        this->m_cap *= 2;
+        this->data = realloc(this->data, this->m_cap * sizeof(element_type));
+    }
+    this->data[this->m_size] = data;
+    ++this->m_size;
 }
-RCPP_CLASS_METHOD_IMPL(vector, at, int, int index) {
-    int element = index * index;
-    return element;
+RCPP_CLASS_METHOD_IMPL(vector, at, element_type, int index) {
+    if(index >= this->m_size) {
+        abort();
+    }
+    return this->data[index];
 }
 
 RCPP_CLASS_CONSTRUCTOR_IMPL(vector) {
     RCPP_CLASS_METHOD_REGISTER(vector, push_back)
     RCPP_CLASS_METHOD_REGISTER(vector, at)
-    printf("constructor called\n");
+    this->m_cap = this->m_size = 0;
+    this->data = NULL;
+    printf("Constructor called!\n");
 }
 RCPP_CLASS_DESTRUCTOR_IMPL(vector) {
-    printf("destructor called\n");
+    if(this->data)
+        free(this->data);
+    printf("Destructor called!\n");
 }
+
 int main(){
     RCPP_NEW(vector, vct, NULL);
-    RCPP_CALL(vct, push_back, 333);
-    vct.push_back(&vct, 666);
+    RCPP_CALL(vct, push_back, 3);
+    RCPP_CALL(vct, push_back, 2);
+    RCPP_CALL(vct, push_back, 1);
+    vct.push_back(&vct, 6);
+    vct.push_back(&vct, 7);
+    vct.push_back(&vct, 8);
 
-    printf("Element at index %d is %d.\n", 5, vct.at(&vct, 5));
-    return 123;
+    for(int cter = 0; cter < vct.m_size; ++cter) {
+        printf("Element at index %d is %d.\n", cter, RCPP_CALL(vct, at, cter));
+    }
+    return 0;
 }
diff --git a/test/src/common.cc b/test/src/common.cc
new file mode 100644
index 0000000000000000000000000000000000000000..e038767f762e006420f3f3cafc2757faba5b19fa
--- /dev/null
+++ b/test/src/common.cc
@@ -0,0 +1,77 @@
+#define CATCH_CONFIG_MAIN
+#include <catch.hpp>
+
+#include <rlib/stdio.hpp>
+#include <stdexcept>
+#include <sstream>
+#include <thread>
+#include <chrono>
+
+void test_f(int);
+class test_c {
+public:
+    auto operator()(int a) {
+        return a;
+    }
+};
+
+#if RLIB_CXX_STD >= 2017
+#include <rlib/functional.hpp>
+#include <rlib/traits.hpp>
+TEST_CASE("functional") {
+    std::stringstream test_ss;
+    auto test_func = [&](int i) {
+        std::this_thread::sleep_for(std::chrono::milliseconds(100));
+        rlib::println(test_ss, "i", i);
+        return i;
+    };
+
+    auto time_cost = rlib::timeof(rlib::repeat(10, test_func, 1));
+    REQUIRE(time_cost > 0.7);
+    REQUIRE_THROWS_AS(rlib::timeof(rlib::repeat(0, test_func, 1)), std::invalid_argument);
+
+    std::string answer;
+    for(auto cter = 0; cter < 10; ++cter) {
+        answer += "i 1" RLIB_IMPL_ENDLINE;
+    }
+    REQUIRE(test_ss.str() == answer);
+
+    auto result = rlib::repeat(2, test_func, 1)();
+    REQUIRE(result == 1);
+    auto result2 = rlib::repeat_and_return_list(2, test_func, 2)();
+    REQUIRE(result2.size() == 2);
+    REQUIRE(*result2.begin() == 2);
+}
+
+TEST_CASE("traits") {
+    auto lmbda = []()->bool{return true;};
+    REQUIRE(rlib::is_callable<test_c>());
+    REQUIRE(rlib::is_callable<decltype(test_f)>());
+    REQUIRE(rlib::is_callable<void()>());
+    REQUIRE(rlib::is_callable<decltype(lmbda)>());
+    REQUIRE(rlib::is_callable<std::function<void(int)>>());
+    REQUIRE_FALSE(rlib::is_callable<int>());
+    REQUIRE_FALSE(rlib::is_callable<std::ostream>());
+}
+#endif // RLIB_CXX_STD > 2017
+
+struct rlib_test_printable {
+    int d = 1;
+    friend std::ostream& operator<< (std::ostream& stream, const rlib_test_printable & p) {
+        stream << p.d;
+        return stream;
+    }
+};
+TEST_CASE("stdio.hpp") {
+    std::stringstream test_ss;
+    rlib::print(test_ss, '>');
+    rlib::println(test_ss, "a", 'b', 123, 0.25, rlib_test_printable{2});
+    REQUIRE(test_ss.str() == ">a b 123 0.25 2" RLIB_IMPL_ENDLINE);
+
+    rlib::printf(test_ss, "{}{}", 1, "");
+    rlib::printfln(test_ss, "hello, {}.", "godaddy");
+    REQUIRE(rlib::scanln(test_ss) == ">a b 123 0.25 2");
+    REQUIRE(rlib::scanln(test_ss) == "1hello, godaddy.");
+}
+
+
diff --git a/test/src/functional.cc b/test/src/functional.cc
deleted file mode 100644
index 3ffb37d5ba909518a8fb53b1cd4d88a7d0a2ca82..0000000000000000000000000000000000000000
--- a/test/src/functional.cc
+++ /dev/null
@@ -1,25 +0,0 @@
-#include <rlib/functional.hpp>
-#include <rlib/stdio.hpp>
-
-
-int main() {
-//    auto f = rlib::repeat(4, [](int i){
-//            rlib::println("i is", i);
-//            }, 777);
-//    f();
-    auto m = [](int i){
-        rlib::println("i is", i);
-    };
-    std::function<void(int)> b (m);
-    auto f = rlib::repeat(4, m, 777);
-//    f(4,m,444);
-//    auto ff = std::bind(&decltype(f)::operator(), &f, 4, m, 444);
-    //std::function<void(size_t, decltype(m), int)> goodf(f);
-
-//    auto ff = std::bind(f, 4,m,444);
-    f();
-
-    rlib::println("time of f is", rlib::timeof(f));
-
-}
-
diff --git a/test/src/print.cc b/test/src/print.cc
deleted file mode 100644
index fd4f0852de1f5fac13cecacde2cedf079f98747a..0000000000000000000000000000000000000000
--- a/test/src/print.cc
+++ /dev/null
@@ -1,11 +0,0 @@
-#include <rlib/stdio.hpp>
-#include <rlib/terminal.hpp>
-using namespace rlib;
-using namespace rlib::terminal;
-
-int main() {
-    auto cter = printfln("{}Hello, {}={}, miao{}.{}", color_t::red, 6.6, 7, "www", clear);
-    printfln("cter={}.", cter);
-    println("test");
-    return 0;
-}
diff --git a/test/src/string.cc b/test/src/string.cc
index 8a711e0199cfef977a46f3948c9022f6a7d10ea7..82d784689d8b8bfc7ea17054582954603768494a 100644
--- a/test/src/string.cc
+++ b/test/src/string.cc
@@ -1,6 +1,6 @@
 #define CATCH_CONFIG_MAIN
 
-#include "../catch.hpp"
+#include <catch.hpp>
 
 #include <rlib/string.hpp>
 #include <stdexcept>
diff --git a/traits.hpp b/traits.hpp
index 43eda722402cd88f75b535c580fd1836a164ab52..f15fba33d619885e8b81300741a1fc76f6689898 100644
--- a/traits.hpp
+++ b/traits.hpp
@@ -22,22 +22,16 @@ namespace rlib{
             template<typename C>
             static no test(Check<void (Fallback::*)(), &C::operator()>*);
     
-        public:
             static constexpr bool value = sizeof(test<Derived>(0)) == sizeof(yes);
+        public:
+            static constexpr bool real_value = std::conditional<std::is_class<T>::value, impl::is_callable_helper<T>, std::is_function<T>>::type::value;
         };
     } //impl
 } //rlib
 
 namespace rlib {
     template<typename T>
-    struct is_callable {
-        using _impl = typename std::conditional<std::is_class<T>::value, impl::is_callable_helper<T>, std::is_function<T>>::type;
-        static constexpr bool value() noexcept {
-            return _impl::value;
-        }
-        constexpr operator bool() noexcept {
-            return is_callable<T>::value();
-        }
+    struct is_callable : public std::bool_constant<impl::is_callable_helper<T>::real_value> {
     };
 }