Type safe - Zero overhead utilities for preventing bugs at compile time

type_safe

Project Status Build Status

type_safe provides zero overhead abstractions that use the C++ type system to prevent bugs.

Zero overhead abstractions here and in following mean abstractions that have no cost with optimizations enabled, but may lead to slightly lower runtime in debug mode, especially when assertions for this library are enabled.

The library features cannot really be explained in the scope of this readme, I highly suggest that you check out the first and second blog post and the examples.

Sponsored by Embarcadero C++Builder.

If you like this project, consider supporting me.

Features

Improved built-in types

  • ts::integer<T> - a zero overhead wrapper over a built-in integer type
    • no default constructor to force meaningful initialization
    • no "lossy" conversions (i.e. from a bigger type or a type with a different signedness)
    • no mixed arithmetic/comparison with floating points or integer types of a different signedness
    • over/underflow is undefined behavior in release mode - even for unsigned integers, enabling compiler optimizations
  • ts::floating_point<T> - a zero overhead wrapper over a built-in floating point
    • no default constructor to force meaningful initialization
    • no "lossy" conversion (i.e. from a bigger type)
    • no "lossy" comparisons
    • no mixed arithmetic/comparison with integers
  • ts::boolean - a zero overhead wrapper over bool
    • no default constructor to force meaningful initialization
    • no conversion from integer values
    • no arithmetic operators
  • aliases like ts::uint32_t or ts::size_t that are either wrapper or built-in type depending on macro
  • literal operators for those aliases like 342_u32 or 0_usize

Vocabulary types

  • ts::object_ref<T> - a non-null pointer
  • ts::index_t and ts::distance_t - index and distance integer types with only a subset of operations available
  • ts::array_ref<T> - non-null reference to contigous storage
  • ts::function_ref<T> - non-null reference to a function
  • ts::flag - an improved flag type, better than a regular bool or ts::boolean
  • ts::flag_set<Enum> - a set of flags
  • ts::output_parameter<T> - an improved output parameter compared to the naive lvalue reference

Optional & Variant

  • ts::basic_optional<StoragePolicy> - a generic, improved std::optional that is fully monadic, also ts::optional<T> and ts::optional_ref<T> implementations
  • ts::compact_optional implementation for no space overhead optionals
  • ts::basic_variant<VariantPolicy, Types...> - a generic, improved std::variant, also ts::variant and ts::fallback_variant implementations

Type safe building blocks

  • ts::constrained_type<T, Constraint, Verifier> - a wrapper over some type that verifies that a certain constraint is always fulfilled
    • ts::constraints::* - predefined constraints like non_null, non_empty, ...
    • ts::tagged_type<T, Constraint> - constrained type without checking, useful for tagging
    • ts::bounded_type<T> - constrained type that ensures a value in a certain interval
    • ts::clamped_type<T> - constrained type that clamps a value to ensure that it is in the certain interval
  • ts::strong_typedef - a generic facility to create strong typedefs more easily
  • ts::deferred_construction<T> - create an object without initializing it yet

Installation

Header-only, just copy the files in your project. You need to add the type_safe include directory to your include path as well as make debug_assert.hpp available. The repository is included. You also need to enable C++11.

Behavior can be customized with the following macros:

  • TYPE_SAFE_ENABLE_ASSERTIONS (default is 1): whether or not assertions are enabled in this library
  • TYPE_SAFE_ENABLE_WRAPPER (default is 1): whether or not the typedefs in type_safe/types.hpp use the wrapper classes
  • TYPE_SAFE_ARITHMETIC_POLICY (ub/checked/default, default is ub): whether under/overflow in the better integer types is UB, an exception, or the default behavior

If you're using CMake there is the target type_safe available after you've called add_subdirectory(path/to/type_safe). Simply link this target to your target and it will setup everything automagically. For convenience the macros are also mapped to CMake options of the same name.

Documentation

You can find the full documentation generated by standardese here.

Acknowledgements

This project is greatly supported by my patrons. In particular thanks to the individual supporters:

  • Mark Atkinson
  • Reiner Eiteljörge

And big thanks to the main contributors as well:

Owner
Jonathan Müller
Interested in C++, I write libraries and blog about them.
Jonathan Müller
Comments
  • CMake Install

    CMake Install

    Hi there,

    I've been doing a bunch of investigation into modern CMake approaches when it comes to library design and type_safe looks like an excellent example of this.

    I may well be at fault here and may not be understanding something correctly but I've run into an issue when attempting to install the type_safe library and use it via find_package (I may be mistaken that this is possible/advised?).

    It appears as though type_safe-config.cmake is not installed to the correct location.

    The steps I took are as follows:

    1. Cloned type_safe repo to <my-project>/external/type_safe
    2. Created a build folder there (<my-project>/external/type_safe/build)
    3. Ran cmake .. to generate the build files
    4. I then ran cmake --build . --target install
    5. After running this, I get this output:
        -- Install configuration: "" (missing config file here?)
        -- Up-to-date: /usr/local/include/type_safe
        -- ... etc. (all other type_safe files...)
    
    1. I have a crazy simple project attempting to consume the library, the CMakeLists.txt file looks like this:
    cmake_minimum_required(VERSION 3.8)
    
    find_package(type_safe REQUIRED)
    
    add_executable(test main.cpp)
    
    target_compile_features(test PRIVATE cxx_variadic_templates)
    target_link_libraries(test PUBLIC type_safe)
    
    1. However when I run cmake .., I get this error:
    By not providing "Findtype_safe.cmake" in CMAKE_MODULE_PATH this project
      has asked CMake to find a package configuration file provided by
      "type_safe", but CMake did not find one.
    
      Could not find a package configuration file provided by "type_safe" with
      any of the following names:
    
        type_safeConfig.cmake
        type_safe-config.cmake
    
      Add the installation prefix of "type_safe" to CMAKE_PREFIX_PATH or set
      "type_safe_DIR" to a directory containing one of the above files.  If
      "type_safe" provides a separate development package or SDK, be sure it has
      been installed.
    
    1. If I instead however do this in the CMakeLists.txt file:
    cmake_minimum_required(VERSION 3.8)
    
    add_subdirectory(external/type_safe) # not using find_package()
    
    add_executable(test main.cpp)
    
    target_compile_features(test PRIVATE cxx_variadic_templates)
    target_link_libraries(test PUBLIC type_safe)
    

    everything builds correctly and I can use the library. My main.cpp looks like this:

    #include <stdio.h>
    
    #include "type_safe/integer.hpp"
    
    int main(int argc, char** argv)
    {
        type_safe::integer<int> answer = 42;
        printf("The answer is: %d\n", answer.get());
    
        return 0;
    }
    

    Essentially my basic question is should I be able to use type_safe with the find_package() mechanism in CMake, or should I just use the add_subdirectory approach?

    I'm interested in writing my own header only library and want to make sure I better understand the modern CMake approaches (INSTALL/EXPORT/Packages etc..) I have to admit I find it all quite confusing :( I read your blog entry https://foonathan.net/blog/2016/03/03/cmake-install.html which was super interesting but to the uninitiated is still quite overwhelming :P.

    Thank you very much for your time,

    All the best,

    Tom

  • Overly restrictive conversion between integer instantiations

    Overly restrictive conversion between integer instantiations

    Hi Jonathan!

    Looking at your documentation for type_safe and saw this about integer:

    A conversion is considered safe if both integer types have the same signedness and the size of the value being converted is less than or equal to the destination size.

    But what if you are converting, say, from uint16_t to int32_t? Is this not allowed? Is it not safe?

    BTW, I have a similar test with no such restriction.

    Cheers, John

  • How to constraint a semantic type?

    How to constraint a semantic type?

    I'm currently evaluating "type_safe" and consider to include it into a software project. The type safety features for primitive types look awesome and I also think that the two concepts "semantic types" and "constrained types" can improve our code.

    There is at least one thing I can't figure out on my own: How can one define constraints for a semantic type?

    Consider the following simple semantic type (no constraints yet):

    struct Percent final
        : type_safe::strong_typedef<Percent, std::uint32_t>,
          type_safe::strong_typedef_op::output_operator<Percent>,
          type_safe::strong_typedef_op::equality_comparison<Percent>,
          type_safe::strong_typedef_op::relational_comparison<Percent> {
      using strong_typedef::strong_typedef;
    };
    

    I know that I can declare a constrained type with a type alias as follows.

    using PercentInt =
        type_safe::bounded_type<std::uint32_t,
                                true,
                                true,
                                std::integral_constant<std::uint32_t, 0>,
                                std::integral_constant<std::uint32_t, 100>>;
    

    But this isn't good enough! I would like to combine the semantic type Percent with the constraint.

    I couldn't find any mention of this feature in blog posts or the examples directory.

    1. Is it generally possible to combine semantic types with constrained types with "type_safe"?
    2. How to declare a constraint, e.g. a bounded constraint (value 0-100, inclusive) for the Percent type?
  • Enabled `std::hash` for `strong_typedef`s with `strong_typedef_op::hashable`

    Enabled `std::hash` for `strong_typedef`s with `strong_typedef_op::hashable`

    Greetings.

    I just found myself specializing std::hash for some strong typedefs of mine which are provided for convenience. I thought it'd be great if the library provided a strong_typedef_op that enabled it.

    I am available to write it. Would the name in the title be ok? How about copying the hash tests of other library components?

  • Compile error in reference.hpp when TYPE_SAFE_ENABLE_WRAPPER is disabled

    Compile error in reference.hpp when TYPE_SAFE_ENABLE_WRAPPER is disabled

    Consider this code:

    #include <type_safe/reference.hpp>
    
    int main()
    {
      return 0;
    }
    

    On Apple Clang 8.1 (at least) it fails to compile when TYPE_SAFE_ENABLE_WRAPPER is disabled because of this error:

    $ clang++ -std=c++14 -DTYPE_SAFE_ENABLE_WRAPPER=0 issue.cpp
    In file included from issue.cpp:1:
    type_safe/include/type_safe/reference.hpp:375:34: error: member reference base type
          'const size_t' (aka 'const unsigned long') is not a structure or union
                return begin_ + size_.get();
                                ~~~~~^~~~
    1 error generated.
    

    Calling get(size_) instead of size_.get() fixes the problem.

  • strong_typedef of user-defined types with non-constexpr operators

    strong_typedef of user-defined types with non-constexpr operators

    Using the provided type_safe::strong_typedef_op mixins with a user-defined type with non-constexpr operators fails in Visual C++ and gcc. It appears to work in clang, which is interesting.

    Visual C++ clang

    Since the mixins are provided as convenience, I can create non-constexpr mixins as needed. I'm not sure how you'd want to address this, if at all, in the lib.

  • Future of type_safe

    Future of type_safe

    Thank you all for making this my most popular project with tons of daily clones!

    However, I never intended that this would be such a widely used library. It started out as an experimentation ground for type safe programming techniques and then turned into my general utility library: I need an optional -> let's put it in type safe. I need a flag set -> let's put it in type safe. etc

    But now it has become this huge project, so I'm not sure how to go from here.

    As shown in the readme this library consists of basically three things:

    • improved integer types
    • type safe building blocks like strong typedefs or constrained type
    • vocabulary types and optional/variant

    If you just want improved integer types there are better and more advanced libraries. I don't think many people actually use the type safe building blocks other than the strong typedefs facility. And the vocabulary types are there because it has become my utility library. They're useful but don't really fit the label "type safe".

    So I think people come and use this library for mainly two reasons:

    1. The strong typedefs facility
    2. The vocabulary types

    Please correct me if I'm wrong in that assessment. (I could be completely off the tracks there)

    I'm thus proposing the following plan:

    1. Extract two other libraries out of type_safe: A strong typedefs library and a vocabulary type library.

      The strong typedefs library will be fully compatible, it is just the strong_typedefs.hpp header split into multiple files and with some more operations.

      The vocabulary type library will have some breaking changes, around optional and variant. I've learned a lot while doing them and like to revise some of my design decisions.

    2. Maybe submit the strong typedef library to Boost. It would still be usable stand alone, but it might make it easier to use in some corporations.

    3. Sometime in 2019 probably: Deprecate the stuff that has been extracted into other libraries.

    This plan allows me to do three things:

    1. Keep type_safe as a library for type safe programming (only)
    2. Put part of it into Boost.
    3. Do some breaking changes to allow better vocabulary types.

    Please let me know what you think of this plan.

  • Compilation error in gcc 4.8.4

    Compilation error in gcc 4.8.4

    Hi

    compilation fails on Ubuntu 14.04 (gcc 4.8.4)

    09:34:17: Running steps for project type_safe...
    09:34:17: Starting: "/usr/bin/cmake" --build . --target all
    Scanning dependencies of target type_safe_example_constrained
    [  5%] Building CXX object example/CMakeFiles/type_safe_example_constrained.dir/constrained.cpp.o
    Linking CXX executable type_safe_example_constrained
    [  5%] Built target type_safe_example_constrained
    Scanning dependencies of target type_safe_example_optional
    [ 11%] Building CXX object example/CMakeFiles/type_safe_example_optional.dir/optional.cpp.o
    In file included from /home/davide/Software/type_safe/example/optional.cpp:9:0:
    /home/davide/Software/type_safe/include/type_safe/optional.hpp: In instantiation of ‘class type_safe::basic_optional<type_safe::direct_optional_storage<char> >’:
    /home/davide/Software/type_safe/example/optional.cpp:15:47:   required from here
    /home/davide/Software/type_safe/include/type_safe/optional.hpp:350:14: error: call of overloaded ‘get_value()’ is ambiguous
             auto value() const && noexcept -> decltype(std::move(policy_).get_value())
                  ^
    /home/davide/Software/type_safe/include/type_safe/optional.hpp:350:14: note: candidates are:
    /home/davide/Software/type_safe/include/type_safe/optional.hpp:828:32: note: const T& type_safe::direct_optional_storage<T>::get_value() const & [with T = char; type_safe::direct_optional_storage<T>::const_lvalue_reference = const char&]
             const_lvalue_reference get_value() const& noexcept
                                    ^
    /home/davide/Software/type_safe/include/type_safe/optional.hpp:842:32: note: const T&& type_safe::direct_optional_storage<T>::get_value() const && [with T = char; type_safe::direct_optional_storage<T>::const_rvalue_reference = const char&&]
             const_rvalue_reference get_value() const&& noexcept
                                    ^
    /home/davide/Software/type_safe/include/type_safe/optional.hpp: In instantiation of ‘class type_safe::basic_optional<type_safe::direct_optional_storage<int> >’:
    /home/davide/Software/type_safe/example/optional.cpp:21:32:   required from here
    /home/davide/Software/type_safe/include/type_safe/optional.hpp:350:14: error: call of overloaded ‘get_value()’ is ambiguous
             auto value() const && noexcept -> decltype(std::move(policy_).get_value())
                  ^
    /home/davide/Software/type_safe/include/type_safe/optional.hpp:350:14: note: candidates are:
    /home/davide/Software/type_safe/include/type_safe/optional.hpp:828:32: note: const T& type_safe::direct_optional_storage<T>::get_value() const & [with T = int; type_safe::direct_optional_storage<T>::const_lvalue_reference = const int&]
             const_lvalue_reference get_value() const& noexcept
                                    ^
    /home/davide/Software/type_safe/include/type_safe/optional.hpp:842:32: note: const T&& type_safe::direct_optional_storage<T>::get_value() const && [with T = int; type_safe::direct_optional_storage<T>::const_rvalue_reference = const int&&]
             const_rvalue_reference get_value() const&& noexcept
                                    ^
    /home/davide/Software/type_safe/include/type_safe/optional.hpp: In instantiation of ‘class type_safe::basic_optional<type_safe::direct_optional_storage<type_safe::basic_optional<type_safe::direct_optional_storage<int> > > >’:
    /home/davide/Software/type_safe/include/type_safe/optional.hpp:83:97:   required by substitution of ‘template<class Optional> using unwrap_optional_t = typename std::decay<typename std::conditional<type_safe::detail::is_optional_impl<typename std::decay<typename std::decay<_Tp>::type::value_type>::type>::value, typename std::decay<_Tp>::type::value_type, typename std::decay<_Tp>::type>::type>::type [with Optional = type_safe::basic_optional<type_safe::direct_optional_storage<char> >::rebind<type_safe::basic_optional<type_safe::direct_optional_storage<int> > >]’
    /home/davide/Software/type_safe/include/type_safe/optional.hpp:438:14:   required by substitution of ‘template<class Func> type_safe::detail::unwrap_optional_t<decltype (this->.map(forward<Func>(f)))> type_safe::basic_optional<StoragePolicy>::bind(Func&&) && [with Func = Func; StoragePolicy = type_safe::direct_optional_storage<char>] [with Func = type_safe::basic_optional<type_safe::direct_optional_storage<int> > (&)(char)]’
    /home/davide/Software/type_safe/example/optional.cpp:55:21:   required from here
    /home/davide/Software/type_safe/include/type_safe/optional.hpp:350:14: error: call of overloaded ‘get_value()’ is ambiguous
             auto value() const && noexcept -> decltype(std::move(policy_).get_value())
                  ^
    /home/davide/Software/type_safe/include/type_safe/optional.hpp:350:14: note: candidates are:
    /home/davide/Software/type_safe/include/type_safe/optional.hpp:828:32: note: const T& type_safe::direct_optional_storage<T>::get_value() const & [with T = type_safe::basic_optional<type_safe::direct_optional_storage<int> >; type_safe::direct_optional_storage<T>::const_lvalue_reference = const type_safe::basic_optional<type_safe::direct_optional_storage<int> >&]
             const_lvalue_reference get_value() const& noexcept
                                    ^
    /home/davide/Software/type_safe/include/type_safe/optional.hpp:842:32: note: const T&& type_safe::direct_optional_storage<T>::get_value() const && [with T = type_safe::basic_optional<type_safe::direct_optional_storage<int> >; type_safe::direct_optional_storage<T>::const_rvalue_reference = const type_safe::basic_optional<type_safe::direct_optional_storage<int> >&&]
             const_rvalue_reference get_value() const&& noexcept
                                    ^
    /home/davide/Software/type_safe/example/optional.cpp: In function ‘int task_monadic(const string&)’:
    /home/davide/Software/type_safe/example/optional.cpp:57:10: error: request for member ‘value_or’ in ‘type_safe::basic_optional<StoragePolicy>::map(Func&&) && [with Func = task_monadic(const string&)::__lambda4; StoragePolicy = type_safe::direct_optional_storage<char>; type_safe::basic_optional<StoragePolicy>::rebind<decltype (forward<Func>(f)(std::move(this->.value())))> = type_safe::basic_optional<type_safe::direct_optional_storage<char> >; typename StoragePolicy::rebind<decltype (forward<Func>(f)(std::move(this->.value())))> = type_safe::direct_optional_storage<char>]((* &<lambda closure object> task_monadic(const string&)::__lambda4{})).type_safe::basic_optional<StoragePolicy>::bind<type_safe::basic_optional<type_safe::direct_optional_storage<int> > (&)(char)>((* lookup))’, which is of non-class type ‘::’
             .value_or(0);
              ^
    /home/davide/Software/type_safe/include/type_safe/optional.hpp:438: confused by earlier errors, bailing out
    Preprocessed source stored into /tmp/cchCeNth.out file, please attach this to your bugreport.
    make[2]: *** [example/CMakeFiles/type_safe_example_optional.dir/optional.cpp.o] Error 1
    make[1]: *** [example/CMakeFiles/type_safe_example_optional.dir/all] Error 2
    make: *** [all] Error 2
    09:34:18: The process "/usr/bin/cmake" exited with code 2.
    Error while building/deploying project type_safe (kit: Desktop)
    When executing step "Make"
    09:34:18: Elapsed time: 00:01.
    
  • Implement safe integer comparison similar to P0586R2

    Implement safe integer comparison similar to P0586R2

    This PR implements unsafe integer comparison - and makes it safe.

    The PR will close #80. The interface is modeled after P0586R2 and the implementation follows the reference implementation from cppreference.

    With a C++11 compiler, one can compare integers as:

    #include <type_safe/integer.hpp>
    #include <cassert>
    
    int main()
    {
      using i32 = type_safe::integer<int>;
      using u32 = type_safe::integer<unsigned int>;
    
      const i32 a(-1);
      const u32 b(1u);
    
      assert(type_safe::cmp_less(a, b));
    
      return 0;
    }
    

    With a C++14 compliant compiler, the compare functions are constexpr and I have additionally overloaded the comparison operators for convenience:

    #include <type_safe/integer.hpp>
    
    int main()
    {
      using i32 = type_safe::integer<int>;
      using u32 = type_safe::integer<unsigned int>;
    
      constexpr i32 a(-1);
      constexpr u32 b(1u);
    
      static_assert(type_safe::cmp_less(a, b));
      static_assert(a < b);
    
      return 0;
    }
    

    Any thoughts on the implementation?

  • std::hash specializations for boolean, integer and floating_point type wrappers

    std::hash specializations for boolean, integer and floating_point type wrappers

    This is a partial-solution to https://github.com/foonathan/type_safe/issues/52 I wanted to create a sample for review before I finish building hash specializations for the remaining type wrappers; please share any feedback you have for these implementations.

  • type_safe::boolean with std::set

    type_safe::boolean with std::set

    Hello,

    I am unable to use strong_typedefs with std::set because the STL cannot convert type_safe::boolean to a bool value.

    Here is an example of what I am trying to do:

    struct thread_id :
      type_safe::strong_typedef<thread_id, type_safe::integer<uint32_t>>,
      type_safe::strong_typedef_op::equality_comparison<thread_id>,
      type_safe::strong_typedef_op::relational_comparison<thread_id>,
      type_safe::strong_typedef_op::output_operator<thread_id>
    {
      using strong_typedef::strong_typedef;
    };
    
    int main(int argc, char ** argv)
    {
      std::set<thread_id> subscribers;
      thread_id subscriber(0u);
    
      subscribers.insert(subscriber); // error here
    
      return 0;
    }
    

    And here is the error:

    /usr/include/c++/5/bits/stl_function.h: In instantiation of ‘constexpr bool std::less<_Tp>::operator()(const _Tp&, const _Tp&) const [with _Tp = thread_id]’: /usr/include/c++/5/bits/stl_tree.h:1810:11: required from ‘std::pair<std::_Rb_tree_node_base*, std::_Rb_tree_node_base*> std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_get_insert_unique_pos(const key_type&) [with _Key = thread_id; _Val = thread_id; _KeyOfValue = std::_Identity<thread_id>; _Compare = std::less<thread_id>; _Alloc = std::allocator<thread_id>; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::key_type = thread_id]’ /usr/include/c++/5/bits/stl_tree.h:1863:28: required from ‘std::pair<std::_Rb_tree_iterator<_Val>, bool> std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_insert_unique(_Arg&&) [with _Arg = const thread_id&; _Key = thread_id; _Val = thread_id; _KeyOfValue = std::_Identity<thread_id>; _Compare = std::less<thread_id>; _Alloc = std::allocator<thread_id>]’ /usr/include/c++/5/bits/stl_set.h:485:29: required from ‘std::pair<typename std::_Rb_tree<_Key, _Key, std::_Identity<_Key>, _Compare, typename __gnu_cxx::__alloc_traits<_Alloc>::rebind<_Key>::other>::const_iterator, bool> std::set<_Key, _Compare, _Alloc>::insert(const value_type&) [with _Key = thread_id; _Compare = std::less<thread_id>; _Alloc = std::allocator<thread_id>; typename std::_Rb_tree<_Key, _Key, std::_Identity<_Key>, _Compare, typename __gnu_cxx::__alloc_traits<_Alloc>::rebind<_Key>::other>::const_iterator = std::_Rb_tree_const_iterator<thread_id>; std::set<_Key, _Compare, _Alloc>::value_type = thread_id]’ /home/badrmari/Projects/phd/sim-sync/src/sim-sync-cl/main.cpp:21:32: required from here /usr/include/c++/5/bits/stl_function.h:387:22: error: cannot convert ‘type_safe::boolean’ to ‘bool’ in return { return __x < __y; }

    Is there a way to fix this with an additional strong_typedef_op? Or is strong_typedef incompatible with STL containers that need to do comparisons?

    (Using gcc 5.4.0)

  • std::aligned_storage_t are deprecated in C++23

    std::aligned_storage_t are deprecated in C++23

    In C++ 23 alignem and is normally replace using things like alignas(T) std::byte t_buff[sizeof(T)].

    alignas has been around since C++ 11 so I am assuming it is OK to just do a direct replacement rather than some ifdef allowing use of the old one

    There are a couple of fairly diect replacement but one that I was unsure about

        template <typename... Types>
        struct aligned_union
        {
            static constexpr auto size_value      = detail::max(sizeof(Types)...);
            static constexpr auto alignment_value = detail::max(alignof(Types)...);
    
            using type = typename std::aligned_storage<size_value, alignment_value>::type;
        };
    

    This seems to be a variant of std::aligned_union which is also deprecated in C++23. The most one to one replacement I can think of is

        template <typename... Types>
        struct aligned_union
        {
            static constexpr auto size_value      = detail::max(sizeof(Types)...);
            static constexpr auto alignment_value = detail::max(alignof(Types)...);
    
            struct type { alignas(alignment_value) std::byte data[size_value]; };
        };
    

    but I have never used any form of alignmet stuff before.

    Note also things like

        template <typename T, typename... Ts>
        constexpr const T& max(const T& t, const Ts&... ts)
    

    would also appear to be just replicas of stuff available in the standard library.

  • Bitwise operations for integer_ops

    Bitwise operations for integer_ops

    Cool library!

    The type_safe::strong_typedef_op could use the bitwise operations like &, |, ~, etc. For the integer op type these should probably be default.

  • strong_typedef: numeric_limits

    strong_typedef: numeric_limits

    I'm new to this lib, but I like the idea very much.

    What about numeric_limits? I know that std::chrono:duration defines them on the type itself, but I would also be happy with some external limits type. What I don't like is this amount of characters:

    struct my_type
        : type_safe::strong_typedef<my_type, std::int32_t>
        , type_safe::strong_typedef_op::equality_comparison<my_type>
        , type_safe::strong_typedef_op::relational_comparison<my_type>
        , type_safe::strong_typedef_op::integer_arithmetic<my_type>
    {}
    constexpr my_type max { std::numeric_limits<ts::underlying_type<my_type>>::max() };
    

    what about something like my_type::max()?

  • flag_set iterator(s) and/or for_each(flag_set<E>, [](E){})

    flag_set iterator(s) and/or for_each(flag_set, [](E){})

    As many programmers I sometimes need to do some work for all flags set in an flag_set.

    Can we add an type_safe way to iterate over all 'set' flags in an flag_set? e.g.

    enum class my_enum; // some flag_set compatible enum class
    
    void do_something_with(my_enum e);
    
    {
      type_safe::flag_set<my_enum> some_flag_set();
    
      type_safe::for_each(
        some_flag_set,
        [](f){ do_something_with(f); }
      );
    }
    
Jimp-native is a fast C++ re-implementation of Jimp with zero system dependencies and minimal overhead!

Jimp native Make your sever-side Jimp code run 10x faster! Jimp-native is a fast C++ re-implementation of Jimp with zero system dependencies and minim

Oct 10, 2022
Entity-Component-System (ECS) with a focus on ease-of-use, runtime extensibility and compile-time type safety and clarity.
Entity-Component-System (ECS) with a focus on ease-of-use, runtime extensibility and compile-time type safety and clarity.

Kengine The Koala engine is a type-safe and self-documenting implementation of an Entity-Component-System (ECS), with a focus on runtime extensibility

Dec 26, 2022
PikaScript is an ultra-lightweight Python engine with zero dependencies and zero-configuration, that can run with 4KB of RAM (such as STM32G030C8 and STM32F103C8), and is very easy to deploy and expand.
PikaScript is an ultra-lightweight Python engine with zero dependencies and zero-configuration, that can run with 4KB of RAM (such as STM32G030C8 and STM32F103C8), and is very easy to deploy and expand.

PikaScript 中文页| Star please~ 1. Abstract PikaScript is an ultra-lightweight Python engine with zero dependencies and zero-configuration, that can run

Dec 29, 2022
oZKS (Ordered Zero-Knowledge Set) is a library that provides an implementation of an Ordered (and Append Only) Zero-Knowledge Set.

Ordered Zero-Knowledge Set - oZKS Introduction oZKS is a library that provides an implementation of an Ordered (and Append Only) Zero Knowledge Set. A

Dec 20, 2022
Embed read-only filesystems into any C++11 program w. a single header, zero dependencies and zero modifications to your code

c-embed Embed read-only filesystems into any C++11 program w. a single header, zero dependencies and zero modifications to your code. Usage c-embed al

Dec 29, 2022
"SaferCPlusPlus" is essentially a collection of safe data types intended to facilitate memory and data race safe C++ programming

A collection of safe data types that are compatible with, and can substitute for, common unsafe native c++ types.

Nov 24, 2022
EntityX - A fast, type-safe C++ Entity-Component system

EntityX - A fast, type-safe C++ Entity Component System NOTE: The current stable release 1.0.0 breaks backward compatibility with < 1.0.0. See the cha

Dec 29, 2022
Type-safe Printf in C

Type-Safe Printf For C This uses macro magic, compound literals, and _Generic to take printf() to the next level: type-safe printing, printing into co

Dec 18, 2022
Not related to software bugs and exploits; this repo contains snippets of code that demonstrate some interesting functionality or a handy trick.

Proof-of-Concept Not related to software bugs and exploits; this repo contains snippets of code that demonstrate some interesting functionality or a h

Nov 19, 2022
OpenDCDiag is an open-source project designed to identify defects and bugs in CPUs.

OpenDCDiag is an open-source project designed to identify defects and bugs in CPUs. It consists of a set of tests built around a sophisticated CPU testing framework. OpenDCDiag is primarily intended for, but not limited to, Data Center CPUs.

Dec 14, 2022
Vulkan and other GPU API bugs I found.
Vulkan and other GPU API bugs I found.

GPU-my-list-of-bugs what is it - list of bugs I found writing shaders, mostly shader bugs. Maybe this is my code bug or/and shader bugs, but this code

Dec 26, 2022
An interpreter for finding subtle bugs in programs written in standard C

tis-interpreter This is tis-interpreter, an interpreter of C for detecting undefined behavior. tis-interpreter detects subtle bugs in C programs that

Dec 21, 2022
PoC that fixes two GTA Online bugs and drastically improves load times for CPU-bound systems

Project status Officially fixed by R* 2021-03-16 :) PoC that fixes two GTA Online bugs and drastically improves load times for CPU-bound systems All a

Jan 5, 2023
GraphicsFuzz provides tools for automatically finding and simplifying bugs in graphics drivers, specifically graphics shader compilers.

GraphicsFuzz GraphicsFuzz is a set of tools for testing shader compilers GraphicsFuzz provides tools for automatically finding and simplifying bugs in

Dec 15, 2022
A C library for runtime-flippable feature flags on Linux/x86-64, with negligible overhead in the common case

Biased runtime-flippable flags, with cross-modifying code The dynamic_flag library is a two-file "C" library that offers efficient biased conditionals

Dec 14, 2022
A plugin that can display player information overhead
 A plugin that can display player information overhead

A plugin that can display player information overhead Config File At plugins/HeadShow/config.json { "updateTick":60,

Jun 17, 2022
Lightweight date, time & cron utilities for embedded systems

Lightweight Date, Time & Cron Platform independent Date, Time & Cron Utility library Read first: Documentation Features Written in ANSI C99 Platform i

Oct 31, 2022
Modern C++ 20 compile time OpenAPI parser and code generator implementation

OpenApi++ : openapipp This is a proof of concept, currently under active work to become the best OpenAPI implementation for C++. It allows compile tim

Jan 5, 2023