Skip to content
Snippets Groups Projects
Commit 615ff2b7 authored by Recolic Keghart's avatar Recolic Keghart
Browse files

more tests

parent 6d21eca8
No related branches found
No related tags found
No related merge requests found
# rlib # rlib
[![CodeFactor](https://www.codefactor.io/repository/github/recolic/rlib/badge/master)](https://www.codefactor.io/repository/github/recolic/rlib/overview/master) [![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) ![AWS CodeBuild](https://codebuild.us-west-1.amazonaws.com/badges?uuid=eyJlbmNyeXB0ZWREYXRhIjoiVUEvK3oxVFAzMlZuZkJlSFE1L1VWSU9IWDBmK0ZpRGZ2clArTDE2UTk4QUZNS1RLUEp2K0lVaVBmNmZjWHNpOXZpRktlOU5RV3k0TjNWcHFKVmVwelJFPSIsIml2UGFyYW1ldGVyU3BlYyI6IllnZUwzWndPSEN4NTFPeGoiLCJtYXRlcmlhbFNldFNlcmlhbCI6MX0%3D&branch=master)
Here is recolic's private library... Here is recolic's private library...
......
...@@ -14,9 +14,9 @@ ...@@ -14,9 +14,9 @@
#define RCPP_PCALL(p_objectname,i_funcname, ...) p_objectname->i_funcname(p_objectname, ##__VA_ARGS__) #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_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_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_MEMBER_DECL(type, name) type name;
#define RCPP_CLASS_END() }; #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, ...` #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, ...`
......
...@@ -26,9 +26,10 @@ namespace rlib { ...@@ -26,9 +26,10 @@ namespace rlib {
using return_type = typename std::invoke_result<Func, Args ...>::type; using return_type = typename std::invoke_result<Func, Args ...>::type;
auto operator ()(size_t count, Func f, Args ... args) { auto operator ()(size_t count, Func f, Args ... args) {
std::list<return_type> ret; std::list<return_type> ret;
if(count == 0) return ret;
for(size_t cter = 0; cter < count; ++cter) for(size_t cter = 0; cter < count; ++cter)
ret.push_back(std::move(f(std::forward<Args>(args) ...))); ret.push_back(std::move(f(std::forward<Args>(args) ...)));
return std::move(ret); return ret;
} }
}; };
...@@ -55,6 +56,9 @@ namespace rlib { ...@@ -55,6 +56,9 @@ namespace rlib {
static_assert(std::is_same<return_type, return_type2>::value); static_assert(std::is_same<return_type, return_type2>::value);
static_assert(std::is_same<return_type, return_type3>::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) ...); return std::bind(impl::repeated_func<Func, Args ...>(), count, std::forward<Func>(f), std::forward<Args>(args) ...);
} }
template <class Func, typename... Args> template <class Func, typename... Args>
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include <string> #include <string>
#include <iostream> #include <iostream>
#include <rlib/string.hpp> // format_string #include <rlib/string.hpp> // format_string
#include <type_traits>
#if RLIB_OS_ID == OS_WINDOWS #if RLIB_OS_ID == OS_WINDOWS
#define RLIB_IMPL_ENDLINE "\r\n" #define RLIB_IMPL_ENDLINE "\r\n"
...@@ -24,6 +25,23 @@ ...@@ -24,6 +25,23 @@
#define RLIB_IMPL_ENDLINE "\n" #define RLIB_IMPL_ENDLINE "\n"
#endif #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 { namespace rlib {
// print to custom stream // print to custom stream
template <typename PrintFinalT> template <typename PrintFinalT>
...@@ -55,16 +73,13 @@ namespace rlib { ...@@ -55,16 +73,13 @@ namespace rlib {
return std::move(line); return std::move(line);
} }
// print to stdout // default for std::cout
template <typename PrintFinalT> template <typename... Args>
void print(PrintFinalT reqArg); void println(Args... args);
template <typename Required, typename... Optional>
void print(Required reqArgs, Optional... optiArgs);
template <typename... Optional>
void println(Optional... optiArgs);
template <> template <>
void println(); void println();
template <typename... Args>
void print(Args... args);
template <typename Iterable, typename Printable> template <typename Iterable, typename Printable>
void print_iter(Iterable arg, Printable spliter); void print_iter(Iterable arg, Printable spliter);
template <typename Iterable, typename Printable> template <typename Iterable, typename Printable>
...@@ -73,12 +88,13 @@ namespace rlib { ...@@ -73,12 +88,13 @@ namespace rlib {
void print_iter(Iterable arg); void print_iter(Iterable arg);
template <typename Iterable> template <typename Iterable>
void println_iter(Iterable arg); void println_iter(Iterable arg);
template <typename... Args> template <typename... Args>
size_t printf(const std::string &fmt, Args... args); size_t printf(const std::string &fmt, Args... args);
template <typename... Args> template <typename... Args>
size_t printfln(const std::string &fmt, Args... args); size_t printfln(const std::string &fmt, Args... args);
// implementations below --------------------------------
namespace impl { namespace impl {
#if RLIB_CXX_STD < 2017 #if RLIB_CXX_STD < 2017
extern bool enable_endl_flush; extern bool enable_endl_flush;
...@@ -103,70 +119,7 @@ namespace rlib { ...@@ -103,70 +119,7 @@ namespace rlib {
return os; return os;
} }
template <typename PrintFinalT> // With custom os
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
template <typename PrintFinalT> template <typename PrintFinalT>
void print(std::ostream &os, PrintFinalT reqArg) void print(std::ostream &os, PrintFinalT reqArg)
{ {
...@@ -182,7 +135,7 @@ namespace rlib { ...@@ -182,7 +135,7 @@ namespace rlib {
void println(std::ostream &os, Optional... optiArgs) void println(std::ostream &os, Optional... optiArgs)
{ {
print(os, optiArgs ...); print(os, optiArgs ...);
println(); println(os);
} }
template <> template <>
inline void println(std::ostream &os) inline void println(std::ostream &os)
...@@ -200,35 +153,91 @@ namespace rlib { ...@@ -200,35 +153,91 @@ namespace rlib {
void println_iter(std::ostream &os, Iterable arg, Printable spliter) void println_iter(std::ostream &os, Iterable arg, Printable spliter)
{ {
print_iter(os, arg, spliter); print_iter(os, arg, spliter);
os << rlib::endl; println(os);
} }
template <typename Iterable> template <typename Iterable>
void print_iter(std::ostream &os, Iterable arg) void print_iter(std::ostream &os, Iterable arg)
{ {
for(const auto & i : arg) print_iter(os, arg, ' ');
os << i << ' ';
} }
template <typename Iterable> template <typename Iterable>
void println_iter(std::ostream &os, Iterable arg) void println_iter(std::ostream &os, Iterable arg)
{ {
print_iter(os, arg); println_iter(os, arg, ' ');
os << rlib::endl;
} }
template <typename... Args> template <typename... Args>
size_t printf(std::ostream &os, const std::string &fmt, Args... args) size_t printf(std::ostream &os, const std::string &fmt, Args... args)
{ {
std::string to_print = format_string(fmt, args...); std::string to_print = impl::format_string(fmt, args...);
os << to_print; print(os, to_print);
return to_print.size(); return to_print.size();
} }
template <typename... Args> template <typename... Args>
size_t printfln(std::ostream &os, const std::string &fmt, Args... args) size_t printfln(std::ostream &os, const std::string &fmt, Args... args)
{ {
size_t len = rlib::printf(fmt, args...); size_t len = printf(os, fmt, args...);
os << rlib::endl; println(os);
return len + 1; 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) ...);
}
} }
......
...@@ -16,10 +16,13 @@ ...@@ -16,10 +16,13 @@
# os rlib/sys/os.hpp # os rlib/sys/os.hpp
# require rlib/require/*.hpp # require rlib/require/*.hpp
# Test dependency:
# string ---> common
MODULES=string meta trait stdio sio scope_guard MODULES=string meta trait stdio sio scope_guard
EXTRA_FLAGS ?= XTRA_FLAGS ?=
CXXFLAGS=-I. $(EXTRA_FLAGS) CXXFLAGS=-I. -I../.. $(XTRA_FLAGS)
STD ?= 14 STD ?= 14
FLAGS11=-std=c++11 rlib/libr.a FLAGS11=-std=c++11 rlib/libr.a
FLAGS14=-std=c++14 rlib/libr.a FLAGS14=-std=c++14 rlib/libr.a
...@@ -37,7 +40,11 @@ endif ...@@ -37,7 +40,11 @@ endif
POSTFIX=$(STD)_$(CXX) 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: string:
$(CXX) $(CXXFLAGS) src/string.cc $(CXXFLAGS) -o src/string_$(POSTFIX).out $(CXX) $(CXXFLAGS) src/string.cc $(CXXFLAGS) -o src/string_$(POSTFIX).out
......
#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");
}
#include <rlib/c-with-class.h> #include <rlib/c-with-class.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
typedef int element_type;
RCPP_CLASS_DECL(vector) RCPP_CLASS_DECL(vector)
RCPP_CLASS_METHOD_DECL_1(vector, push_back, void, int) RCPP_CLASS_METHOD_EXTERN_DECL(vector, push_back, void, element_type)
RCPP_CLASS_METHOD_DECL_1(vector, at, int, int) RCPP_CLASS_METHOD_EXTERN_DECL(vector, at, element_type, int)
RCPP_CLASS_BEGIN(vector) RCPP_CLASS_BEGIN(vector)
RCPP_CLASS_METHOD_DECL_2(vector, push_back) RCPP_CLASS_METHOD_DECL(vector, push_back, void, element_type)
RCPP_CLASS_METHOD_DECL_2(vector, at) 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_END()
RCPP_CLASS_METHOD_IMPL(vector, push_back, void, int data) { RCPP_CLASS_METHOD_IMPL(vector, push_back, void, element_type data) {
printf("pushing back %d\n", 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) { RCPP_CLASS_METHOD_IMPL(vector, at, element_type, int index) {
int element = index * index; if(index >= this->m_size) {
return element; abort();
}
return this->data[index];
} }
RCPP_CLASS_CONSTRUCTOR_IMPL(vector) { RCPP_CLASS_CONSTRUCTOR_IMPL(vector) {
RCPP_CLASS_METHOD_REGISTER(vector, push_back) RCPP_CLASS_METHOD_REGISTER(vector, push_back)
RCPP_CLASS_METHOD_REGISTER(vector, at) 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) { RCPP_CLASS_DESTRUCTOR_IMPL(vector) {
printf("destructor called\n"); if(this->data)
free(this->data);
printf("Destructor called!\n");
} }
int main(){ int main(){
RCPP_NEW(vector, vct, NULL); RCPP_NEW(vector, vct, NULL);
RCPP_CALL(vct, push_back, 333); RCPP_CALL(vct, push_back, 3);
vct.push_back(&vct, 666); 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)); for(int cter = 0; cter < vct.m_size; ++cter) {
return 123; printf("Element at index %d is %d.\n", cter, RCPP_CALL(vct, at, cter));
}
return 0;
} }
#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.");
}
#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));
}
#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;
}
#define CATCH_CONFIG_MAIN #define CATCH_CONFIG_MAIN
#include "../catch.hpp" #include <catch.hpp>
#include <rlib/string.hpp> #include <rlib/string.hpp>
#include <stdexcept> #include <stdexcept>
......
...@@ -22,22 +22,16 @@ namespace rlib{ ...@@ -22,22 +22,16 @@ namespace rlib{
template<typename C> template<typename C>
static no test(Check<void (Fallback::*)(), &C::operator()>*); static no test(Check<void (Fallback::*)(), &C::operator()>*);
public:
static constexpr bool value = sizeof(test<Derived>(0)) == sizeof(yes); 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 } //impl
} //rlib } //rlib
namespace rlib { namespace rlib {
template<typename T> template<typename T>
struct is_callable { struct is_callable : public std::bool_constant<impl::is_callable_helper<T>::real_value> {
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();
}
}; };
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment