Tiny - low-level library for minimizing the size of your types

Overview

foonathan/tiny

Project Status Build Status

Note: This project is currently WIP, no guarantees are made until an 0.1 release.

This project is a C++11 library for putting every last bit to good use. It combines various techniques such as llvm::PointerIntPair, tombstones and (a custom implementation of) bitfields to write types that use as little bits as possible.

Important: This library is a low-level implementation library. It is meant for experienced C++ programmers who write foundational code, such as vocabulary types, containers etc. As such, the types used by this library should not appear in interfaces directly. Instead they are implementation details of other types. This is especially true for the _impl types such as tiny::optional_impl. Proper vocabulary types are meant to be built on top of them.

Features

Foundations

  • tiny::bit_view: A view for a range of (possibly disjoint) bits. This is a fundamental type used internally and for implementing some traits.
  • tiny::enum_traits: Traits to specify range of an enum. Will be automatically implemented for enumerations with members such as unsigned_count_, but can be specialized for own types. They are required for exposing information about your enumerations.
  • tiny::padding_traits: Traits to specify padding bytes of your type. They basically provide a tiny::bit_view to the bytes that are padding. tiny::padding_traits_aggregate provides a semi-automatic implementation for aggregate types.

Tiny Types

Tiny types are types that are just a couple of bits in size. They cannot be stored directly but instead in a storage type:

  • tiny::tiny_storage: Stores multiple tiny types tightly packed together (think bitfields).

  • tiny::pointer_tiny_storage: Stores tiny types in the alignment bits of a pointer.

  • tiny::padding_tiny_storage: Stores tiny types in the padding of another type.

The tiny types provided by this library:

  • tiny::tiny_bool: a bool
  • tiny::tiny_int<N>/tiny::tiny_unsigned<N>: N bit integers (where N is tiny)
  • tiny::tiny_int_range<Min, Max>: the specified integers
  • tiny::tiny_enum<E>: a tiny enumeration
  • tiny::tiny_flag_set<Flags>: a set of flags, i.e. multiple booleans with names

Tombstones

Optional implementations like std::optional<T> need to have storage for T and a boolean indicating whether or not one is currently stored. Due to alignment and padding this can easily double the size beyond what is necessary.

A tombstone is a special "invalid" value of a type, like a nullptr reference. It can be used to indicate an empty optional without needing to store a boolean.

The tiny::tombstone_traits are a non-intrusive way of exposing tombstones without creating the ability to expose the invalid type states.

Vocabulary Implementation Helpers

A space efficient optional implementation can be built on top of the tombstone traits. However, certain design decisions of such vocabulary types are somewhat controversial. So instead of writing the full implementation, the library contains just the bare minimum. Proper vocabulary types can be built on top.

Those are:

  • tiny::optional_impl: a tombstone enabled and thus compact optional
  • tiny::pointer_variant_impl: a union of multiple pointer types using alignment bits to store the currently active pointer

FAQ

Q: Are those tricks standard conforming C++?

A: For the most part, yes: The implementations are carefully crafted to avoid undefined behavior. However, I'm certainly relying on some implementation-defined behavior. For example, the tiny::pointer_tiny_storage makes some assumptions about the integral representation of pointers that are not necessarily guaranteed, but all implementations I'm aware of work that way. Please let me know if yours don't!

Q: The tiny types behave weird when I use auto.

A: That's not a question, but yes. By their very nature I cannot expose references to a stored tiny type. Proxies are used instead, which interact poorly with auto. This is an implementation limit I can't really do anything about.

Q: It breaks when I do this!

A: Don't do that. And file an issue (or a PR, I have a lot of other projects...).

Q: This is awesome!

A: Thanks. I do have a Patreon page, so consider checking it out:

Patreon

Documentation

A full reference documentation is WIP, look at the comments in the header files for now.

Annotated tutorial style examples can be found in the example directory.

Compiler Support

The library requires a C++11 compiler. Compilers that are being tested on CI:

  • Linux:
    • GCC 5 to 8
    • clang 4 to 7
  • MacOS:
    • XCode 9 and 10
  • Windows:
    • Visual Studio 2017

It only requires the following standard library headers:

  • cstddef and cstdint
  • climits and limits
  • cstdlib (for std::abort) and cstring (for std::memcpy)
  • new (for placement new only)
  • type_traits

The debug_assert library optionally requires cstdio for printing messages to stderr. Defining DEBUG_ASSERT_NO_STDIO disables that.

It does not use exceptions, RTTI or dynamic memory allocation.

Installation

The library is header-only and has only my debug_assert library as dependency.

If you use CMake, debug_assert will be cloned automatically if not installed on the system. You can use it with add_subdirectory() or install it and use find_package(foonathan_tiny), then link to foonathan::foonathan_tiny and everything will be setup automatically.

Planned Features

  • NaN floating point packing
  • More vocabulary type helpers
You might also like...
OSA a is minisatellite/ space probe the size of a can designed to participate in the ESA CanSat 2021 competition 🛰️ 📡 .
OSA a is minisatellite/ space probe the size of a can designed to participate in the ESA CanSat 2021 competition 🛰️ 📡 .

Project OSA OSA a is minisatellite/ space probe the size of a can designed to participate in the ESA CanSat 2021 competition 🛰️ 📡 . Our project is c

Shared to msvcrt.dll or ucrtbase.dll and optimize the C/C++ application file size.
Shared to msvcrt.dll or ucrtbase.dll and optimize the C/C++ application file size.

VC-LTL - An elegant way to compile lighter binaries. 简体中文 I would like to turn into a stone bridge, go through 500 years of wind, 500 years of Sun, ra

esp32s2 implement a  usb port display with 320*240 size with ~13pfs
esp32s2 implement a usb port display with 320*240 size with ~13pfs

esp32s2_usb_display overview it's a USB mini display for Linux platform, such as raspberry Pi, Centos X86 server. it refer many opensource projects: r

Browser and NodeJS Web Assembly audio decoder libraries that are highly optimized for size and performance.

WASM Audio Decoders WASM Audio Decoders is a collection of Web Assembly audio decoder libraries that are highly optimized for browser use. Each module

Program your micro-controllers in a fast and robust high-level language.

Toit language implementation This repository contains the Toit language implementation. It is fully open source and consists of the compiler, virtual

rax/RAX is a C++ extension library designed to provide new, fast, and reliable cross-platform class types.

rax rax/RAX is a C++ extension library designed to provide cross-platform new, fast, and reliable class types for different fields such as work with I

Recursive Variant: A simple library for Recursive Variant Types
Recursive Variant: A simple library for Recursive Variant Types

rva::variant — Recursive Sum Types for C++ Provided by the Recursive Variant Authority. We stand united in opposition to the TVA. May your variants ne

A refactored Proof-of-concept originally developed in 2017 to print all function calls with their arguments data types and values using Ptrace during program execution.

print-function-args-debugger A refactored Proof-of-concept originally developed in 2017 to print all function calls with their arguments data types an

USENIX 2021 - Nyx: Greybox Hypervisor Fuzzing using Fast Snapshots and Affine Types
USENIX 2021 - Nyx: Greybox Hypervisor Fuzzing using Fast Snapshots and Affine Types

Nyx: Greybox Hypervisor Fuzzing using Fast Snapshots and Affine Types Nyx is fast full-VM snapshot fuzzer for type-2 hypervisors. It's built upon kAFL

Comments
  • Getting a reference from a pointer inside a pointer_variant

    Getting a reference from a pointer inside a pointer_variant

    Hey! One of the problems I faced when implementing my tiny::pointer_variant<T*, U*> was to get a T**. Since (in my implementation), the first item of the variant has a 0 bit tag, the pointer actually has a non-dirty bit pattern, so it should be possible to take the pointer to the element inside the variant. I had a hard time implementing that without violating strict aliasing rules. (And I still don't know if I was able to implement that without UB).

    The motivation to get a T** is to be able to create a tiny::pointer_dyn_array<T*>, which is a pointer_variant<T*, T**>, and contains the T* when the array has size 1 (therefore avoiding allocation and indirection in size=1). Since the tiny::pointer_dyn_array<T*> has a begin/end interface, it's necessary to get the T** from the variants first element.

    Is there a plan to implement a pointer_dyn_array? I'm curious to know how you'd implement that.

    opened by brenoguim 1
Owner
Jonathan Müller
Interested in C++, I write libraries and blog about them.
Jonathan Müller
A water tank level sensor **Built With WisBlock** to detect overflow and low level conditions.

RAK12014 Laser TOF sensor coming soon WisBlock Watertank Level Sensor Watertank Overflow detection using the RAKwireless WisBlock modules. It implemen

Bernd Giesecke 3 Feb 3, 2022
Arbitrary Precision provides C++ long integer types that behave as basic integer types. This library aims to be intuitive and versatile in usage, rather than fast.

Arbitrary Precision (AP) Cross-platform and cross-standard header-only arbitrary precision arithmetic library. Currently it offers integer types that

null 17 Sep 28, 2022
My new zigbee project. Wireless temperature and humidity mini sensor with electronic ink display 2.13 inches, low power consumption, compact size, enclosure with magnets.

My new zigbee project. Wireless temperature and humidity mini sensor with electronic ink display 2.13 inches, low power consumption, compact size, enclosure with magnets. The device use SHTC3 sensors, chip CC2530, battery CR2477.

Andrew Lamchenko 20 Nov 20, 2022
S2-LP driver library, low-level and easy-to-port

S2-LP Library This library provides a simple way to use S2-LP transciever module. This library is WIP, but mostly done. https://www.st.com/en/wireless

Wojciech Olech 7 Oct 10, 2022
Low level library to develop GBA games that can also be built for PC.

Universal GBA Library 1. Introduction This is a library for development of GBA games. It can be used to build actual GBA game ROMs, but it can also ta

Antonio Niño Díaz 37 Oct 28, 2022
CC2500 Low-Cost Low-Power 2.4 GHz RF Transceiver driver for esp-idf

esp-idf-cc2500 CC2500 Low-Cost Low-Power 2.4 GHz RF Transceiver driver for esp-idf. I ported from this. 2.00mm pitch External Antena 1.27mm pitch PCB

null 3 May 29, 2022
A list of excellent resources for anyone to deepen their understanding with regards to Windows Kernel Exploitation and general low level security.

WinKernel-Resources A list of excellent resources for anyone trying to deepen their understanding with regards to Windows Kernel Exploitation and gene

Vector Security 55 Nov 12, 2022
A low level Operating System designed using Linux Kernel

Conqueror A low level Operating System designed using Linux Kernel To develop the basic low level operating system, we need following Virtual Machine

mahendra gandham 9 Oct 6, 2022
Volatile ELF payloads generator with Metasploit integrations for testing GNU/Linux ecosystems against low-level threats

Revenant Intro This tool combines SCC runtime, rofi, Msfvenom, Ngrok and a dynamic template processor, offering an easy to use interface for compiling

Red Code Labs 53 Aug 23, 2022