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
[![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...
......
......@@ -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, ...`
......
......@@ -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>
......
......@@ -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) ...);
}
}
......
......@@ -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
......
#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 <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;
}
#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
#include "../catch.hpp"
#include <catch.hpp>
#include <rlib/string.hpp>
#include <stdexcept>
......
......@@ -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> {
};
}
......
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