Skip to content

lucklove/ZBase

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

99 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Useful utils

Build Status Coverage Status

Design principle

  • Header only
  • Low dependence:
    no dependency on other headers(include which from inc/) except which from ISO C++.

Introduction

Functionality Documentation Header Test
Unit testing UnitTest.hh UnitTest.hh see test
Wrap async call to avoid callback hell AsyncWrapper.hh AsyncWrapper.hh here
Danamic generic type Any.hh Any.hh here
Uninitialized concept Optional.hh Optional.hh here
multi-type, single value container Variant.hh Variant.hh here
compile-time function information function_traits.hh here
scope guard ScopeGuard.hh ScopeGuard.hh here

Usage

To use the header, just copy which you need to your include dictionary.

UnitTest.hh

Extremely small unit testing framework.

#define TEST_MAIN       /**< this will insert main function to this compile unit atomaticly */
#include "UnitTest.hh"

TEST_CASE(a_test_case)
{
    TEST_REQUIRE(condition);    /**< if this fail, the next lines in this case will not be executed */
    TEST_CHECK(condition);      /**< if this fail, failure will be report, but test go on */
    TEST_CHECK(condition, "extra dialog msg");  /**< if this fail, "extra dialog msg" will be printed. */
    TEST_REQUIRE(condition, "multi", "line", "extra", "msg");
    TEST_CHECK(condigion, []{ /** do something here */ });
    TEST_REQUIRE(condition, logger, args_to_logger);    /**< logger can be any callable object */
    throw some_thing{msg};      /**< this exception will be caught by unit testing framework and a failure will be report */   
}

TEST_CASE(another_test_case)
{
    *(int *)0 = 0;              /**< the unit test framewrok will caught SIGSEGV and terminate all tests */
}

AsnycWrapper.hh

Designed to avoid deep callback.
Compare codes bellow, you can't miss it.

With lambda, we always do callbacks like this:

async_function(params, [](callback_param_decls)
{
    if(need_do_another_async_operation())
    {
        another_async_function(params, [](callback_param_decls)
        {
            if(need_do_yet_another_async_operation())
            {
                yet_another_async_function(params, [](callback_param_decls)
                {
                    /** what if we need more async operations? */
                }   
            }
        });
    }
});

Now, we can do it in this way:

wrapAsync([](auto callback, callback_param_decls)
{
    async_func(params, callback);
}).then([](auto callback, callback_param_decls)
{
    if(need_do_another_async_operation())
        another_async_function(params, callback);
}).then([](auto callback, callback_param_decls)
{
    if(need_do_yet_another_async_operation())
        yet_another_async_function(params, callback);
}) /**< if need more async operation, just write .then(...), and at then end of the then list, we should: */
.apply();

Any.hh

The Any class is a variant value type based on the second category.
It supports copying of any value type and safe checked extraction of that value strictly against its type.

Any a, b = 47;              /**< a contains null, b contains int(47) */
if(b.is<int>())             /**< check if b contains a int, should be true */
{
    a = b.get<int>();       /**< take which b contains, now a and b both contain int(47) */
    Any c = a;              /**< c contains int instead of Any */
    std::cout << c.get<bool>() << std::endl;   /**< this will throw std::bad_cast */
}

Optional.hh

Class template Optional is a wrapper for representing 'optional' (or 'nullable') objects who may not (yet) contain a valid value.

Optional<int> opt;      /**< maybe contains bool */
if(opt)                 /**< check if opt is initialized, will be false */
{
    /** do something */
}
else
{
    opt = 47;                           /**< now, opt is initialized */
    Optional<int> opt1 = opt;           /**< now, opt and opt1 contains the same thing */
    Optional<std::string> opt2 = opt;   /**< compile error */
    Optional<std::string> opt3 = 3;     /**< compile error */
}

Variant.hh

The variant class template is a safe, generic, stack-based discriminated union container,    
Whereas standard containers such as std::vector may be thought of as "multi-value, single     
type," variant is "multi-type, single value."
Variant<int, bool, std::string> var;    /**< may contains int, bool or std::string */
var = 47;                               /**< now contains int, var.is<int>() will be true */
if(var.is<int>())                       /**< check if var contains int */
    std::cout << var.get<int>() << std::endl;                   /**< get int from variant */
Variant<int, bool, std::string> var1 = var;                     /**< var1 contains the same thing as var */
Variant<int, bool, std::string> var2 = "string";                /**< compile error */
Variant<int, bool, const char*> var3 = "const char*";           /**< ok */
Variant<int, bool, std::string> var4 = std::string{"string"};   /**< ok */

ScopeGuard.hh

HANDLE func()
{
    HANDLE h = CreateSomeObject(...);
    ScopeGuard onErrorExit([&] { CloseHandle(h); h = nullptr; });

    //...
    if(error0_occur)
    {
        return nullptr;
    }

    //...

    if(error1_occur)
    {
        return nullptr;
    }

    //...
    onErrorExit.dismiss()  // no error occur
    return h;
}

About

useful utils(c++14)

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published