Quick Overview
foonathan/type_safe is a C++ library that provides zero-overhead abstractions for safer and more expressive C++ code. It offers strong typedefs, bounded integers, and tagged unions, among other features, to enhance type safety and reduce common programming errors.
Pros
- Improves code safety and readability without runtime overhead
- Provides a set of useful abstractions for common programming patterns
- Header-only library, easy to integrate into existing projects
- Well-documented with extensive examples and explanations
Cons
- Requires C++11 or later, which may limit compatibility with older codebases
- Some features may have a learning curve for developers unfamiliar with advanced C++ techniques
- Might increase compile times due to heavy use of templates
Code Examples
- Creating a strong typedef:
#include <type_safe/strong_typedef.hpp>
TYPE_SAFE_STRONG_TYPEDEF(int, UserId);
void process_user(UserId id) {
// Function can only be called with a UserId, not a raw int
}
- Using a bounded integer:
#include <type_safe/bounded_type.hpp>
using Percentage = type_safe::bounded<int, type_safe::closed_interval<0, 100>>;
Percentage valid(75); // OK
Percentage invalid(150); // Throws an exception
- Working with optional values:
#include <type_safe/optional.hpp>
type_safe::optional<int> maybe_int = 42;
if (maybe_int)
std::cout << *maybe_int << std::endl; // Prints 42
maybe_int = type_safe::nullopt;
if (!maybe_int)
std::cout << "No value" << std::endl; // Prints "No value"
Getting Started
To use foonathan/type_safe in your project:
-
Clone the repository or download the headers:
git clone https://github.com/foonathan/type_safe.git
-
Add the
include
directory to your include path. -
Include the desired headers in your C++ files:
#include <type_safe/strong_typedef.hpp> #include <type_safe/bounded_type.hpp> #include <type_safe/optional.hpp>
-
Compile your project with C++11 or later:
g++ -std=c++11 your_file.cpp -I path/to/type_safe/include
Remember to link against the required dependencies if you're using features that require them (e.g., debug_assert).
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
type_safe
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.
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 with floating points or integer types of a different signedness
- no mixed comparison with floating points
- 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 overbool
- no default constructor to force meaningful initialization
- no conversion from integer values
- no arithmetic operators
- aliases like
ts::uint32_t
orts::size_t
that are either wrapper or built-in type depending on macro - literal operators for those aliases like
342_u32
or0_usize
Vocabulary types
ts::object_ref<T>
- a non-null pointerts::index_t
andts::distance_t
- index and distance integer types with only a subset of operations availablets::array_ref<T>
- non-null reference to contigous storagets::function_ref<T>
- non-null reference to a functionts::flag
- an improved flag type, better than a regularbool
orts::boolean
ts::flag_set<Enum>
- a set of flagsts::output_parameter<T>
- an improved output parameter compared to the naive lvalue reference
Optional & Variant
ts::basic_optional<StoragePolicy>
- a generic, improvedstd::optional
that is fully monadic, alsots::optional<T>
andts::optional_ref<T>
implementationsts::compact_optional
implementation for no space overhead optionalsts::basic_variant<VariantPolicy, Types...>
- a generic, improvedstd::variant
, alsots::variant
andts::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 fulfilledts::constraints::*
- predefined constraints likenon_null
,non_empty
, ...ts::tagged_type<T, Constraint>
- constrained type without checking, useful for taggingts::bounded_type<T>
- constrained type that ensures a value in a certain intervalts::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 easilyts::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 is1
): whether or not assertions are enabled in this libraryTYPE_SAFE_ENABLE_WRAPPER
(default is1
): whether or not the typedefs intype_safe/types.hpp
use the wrapper classesTYPE_SAFE_ARITHMETIC_POLICY
(ub
/checked
/default
, default isub
): 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:
- Johel Ernesto Guerrero Peña @johelegp
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot