Cpp-std-fwd - forward declarations for C++ std headers

Related tags

CLI cpp-std-fwd
Overview

cpp-std-fwd

Forward declarations for most useful runtime classes of the C++ 17 standard library.

DISCLAIMER: This project is meant as a proof-of-concept for a proposal to standardize a forward declaration header for std. Using it is UB and should only be done to evaluate the proposal (see FAQ at the bottom).

Benchmarks

TL;DR: adding #include <stdfwd.hh> adds about 3 ms per translation unit.

file clang-6 clang-7 gcc-7 gcc-8 vs19
empty 12.6 ms 13.9 ms 5.5 ms 5.5 ms 104.8 ms
<stdfwd.hh> + 3.0 ms + 3.3 ms + 2.8 ms + 2.2 ms + 6.7 ms
<type_traits> + 9.9 ms + 10.6 ms + 8.4 ms + 7.2 ms + 28.2 ms
<utility> + 14.1 ms + 14.5 ms + 11.6 ms + 10.2 ms + 31.0 ms
<string_view> + 39.4 ms + 42.1 ms + 36.4 ms + 30.9 ms + 121.6 ms
<vector> + 44.1 ms + 47.4 ms + 41.0 ms + 35.5 ms + 89.9 ms
<string> + 93.1 ms + 99.2 ms + 90.3 ms + 79.8 ms + 137.7 ms
<array> + 95.9 ms + 102.4 ms + 93.8 ms + 83.1 ms + 248.2 ms
<optional> + 100.1 ms + 107.1 ms + 97.6 ms + 87.4 ms + 85.1 ms
<map> + 127.2 ms + 136.0 ms + 123.3 ms + 109.6 ms + 94.9 ms
<memory> + 127.5 ms + 135.3 ms + 124.8 ms + 109.9 ms + 89.2 ms
<iostream> + 137.4 ms + 144.8 ms + 139.6 ms + 121.9 ms + 238.0 ms
<unordered_map> + 142.4 ms + 149.0 ms + 135.6 ms + 126.0 ms + 138.2 ms
<functional> + 180.1 ms + 191.3 ms + 172.7 ms + 156.8 ms + 160.1 ms
<regex> + 297.8 ms + 312.1 ms + 303.1 ms + 262.9 ms + 332.5 ms

Just compiling a single source including the specified file (compiler -std=c++17 -O0 -c /tmp/file.cc -o /tmp/file.o), best out of 10 compilations.

(system: intel i9-9900k 5 GHz, samsung 970 1TB pro nvme ssd, linux mint 19.1 tessa, kernel 4.15.0)

Windows benchmark done on Win10 with /GS /TP /W3 /Zc:wchar_t /Gm- /Od /Ob0 /Zc:inline /fp:precise /WX- /Zc:forScope /RTC1 /GR /Gd /MDd /std:c++17 /FC /EHsc /c.

Usage

Use forward declarations where possible in the header:

#include <stdfwd.hh>

stdfwd::string get_string();
stdfwd::vector<int> get_vector();
stdfwd::deque<int> get_deque();
stdfwd::list<int> get_list();
stdfwd::stack<int> get_stack();
stdfwd::forward_list<int> get_forward_list();
stdfwd::shared_ptr<int> get_shared_ptr();
stdfwd::unique_ptr<int> get_unique_ptr();
stdfwd::array<int, 3> get_array();
stdfwd::function<int()> get_function();
stdfwd::bitset<3> get_bitset();
stdfwd::pair<int, int> get_pair();
stdfwd::map<int, int> get_map();
stdfwd::set<int> get_set();
stdfwd::unordered_map<int, int> get_unordered_map();
stdfwd::unordered_set<int> get_unordered_set();
...

And in the .cc just #include <header> and define the functions using the normal std type (all declarations inside stdfwd are typedefs into std).

std:: forward declarations can also be used but won't have default template arguments (e.g. std::vector<int> does not work and std::vector<int, std::allocator<int>> or stdfwd::vector<int> must be used).

Adding support for map and unordered_map for custom data types:

#include <stdfwd.hh>

struct foo
{
    int v;

    bool operator==(foo const& r) const { return v == r.v; }
};

template <>
struct std::hash<foo>
{
    size_t operator()(foo const& f) const noexcept { return f.v; }
};

template <>
struct std::less<foo>
{
    bool operator()(foo const& a, foo const& b) const noexcept { return a.v < b.v; }
};

CMake

If the CMakeLists.txt is included, an interface library std-fwd is created:

# if set, force-includes "stdfwd.hh" in every translation unit
# this is optional and low-cost (see benchmarks)
# set(STDFWD_FORCE_INCLUDE ON CACHE BOOL "" FORCE)

add_subdirectory(path/to/cpp-std-fwd)

target_link_libraries(${PROJECT_NAME} PUBLIC std-fwd)

FAQ

  • Why?

    Each non-trivial std header adds 50-200 ms compile time just by including them. #include <stdfwd.hh> is virtually free.

  • Isn't adding declarations to std undefined behavior?

    Yes. This project is meant as a proof-of-concept for a proposal to standardize a forward declaration header for std.

  • Why the namespace stdfwd?

    Some classes like std::vector have default template arguments which must only appear on a declaration once. If they appear on the definition then they cannot appear on the forward declaration. Thus, all forward declarations in std are without default arguments and stdfwd adds typedefs with the appropriate defaults.

  • Why are some classes like std::integer_sequence missing?

    I omitted classes that are intended for compile-time programming because there seems to be little reason to forward declare them.

  • What are the use cases?

    Many functions defined in a header but implemented elsewhere don't require complete definitions of their arguments or return types. std::vector<int> foo(); can be defined without including <vector> given forward declarations.

    Furthermore, many data types might want to specialize std::less or std::hash so that their users can use them inside std::map or std::unordered_map. Currently this requires including <functional> (one of the most expensive std headers to include) even if the data type itself uses nothing from that header. With a forward declaration, less and hash can be specialized without including the full header.

  • Won't this be obsolete with modules?

    Yes and no. In C++20, std itself is not yet modularized. Additionally, it is not clear if all code bases can be immediately migrated to modules. This std forward header is a small and easy-to-implement non-intrusive change with big payoffs for many code bases.

  • Why is iosfwd not used internally?

    This header should be as fast as possible. iosfwd includes more than forward declaration. It also fully defines the postypes at least in libstdc++.

Related Work

TODO

  • add support for libc++
You might also like...
Cpp-concurrency - cpp implementation of golang style concurrency

cpp-concurrency C++ implementation of golang style concurrency Usage Use existing single header concurrency.hpp or run script to merge multiple header

Easy to use cryptographic framework for data protection: secure messaging with forward secrecy and secure data storage. Has unified APIs across 14 platforms.
Easy to use cryptographic framework for data protection: secure messaging with forward secrecy and secure data storage. Has unified APIs across 14 platforms.

Themis provides strong, usable cryptography for busy people General purpose cryptographic library for storage and messaging for iOS (Swift, Obj-C), An

 Forward - A library for high performance deep learning inference on NVIDIA GPUs
Forward - A library for high performance deep learning inference on NVIDIA GPUs

a library for high performance deep learning inference on NVIDIA GPUs.

Path Tracking PID offers a tuneable PID control loop, decouling steering and forward velocity
Path Tracking PID offers a tuneable PID control loop, decouling steering and forward velocity

path_tracking_pid Overview Path Tracking PID offers a tuneable PID control loop decouling steerting and forward velocity. The forward velocity is gene

A forward proxy module for CONNECT request handling

name This module provides support for the CONNECT method request. This method is mainly used to tunnel SSL requests through proxy servers. Table of Co

Text - A spicy text library for C++ that has the explicit goal of enabling the entire ecosystem to share in proper forward progress towards a bright Unicode future.

ztd.text Because if text works well in two of the most popular systems programming languages, the entire world over can start to benefit properly. Thi

Node-portmapping allows to forward ports on Network Address Translators (NAT)

Multi-protocol NAT Port Mapping for Node.js node-portmapping allows to forward ports on Network Address Translators (NAT). It implements the protocols

Fast C++ container combining the best features of std::vector and std::deque

veque The double-ended vector A very fast C++17 container combining the best features of std::vector and std::deque "In Most Cases, Prefer Using deque

Invoke.hpp - std::invoke/std::apply analogs for C++11/14

invoke.hpp std::invoke/std::apply analogs for C++11/14 Requirements gcc = 4.9 clang = 3.8 msvc = 2015 Installation invoke.hpp is a header-only libr

:sparkles: Magical headers that make your C++ library accessible from JavaScript :rocket:
:sparkles: Magical headers that make your C++ library accessible from JavaScript :rocket:

Quick start | Requirements | Features | User guide | Contributing | License nbind is a set of headers that make your C++11 library accessible from Jav

C++ mocking made easy. A simple yet very expressive, headers only library for c++ mocking.

FakeIt GCC: MSC: FakeIt is a simple mocking framework for C++. It supports GCC, Clang and MS Visual C++. FakeIt is written in C++11 and can be used fo

Headers and package for CoreSymbolication

CoreSymbolication Headers and package for the CoreSymbolication private framework for macOS. The header is definitely not complete. But, if there's so

A headers only high performance C++ middleware framework/lib. See README for details.

# README # hmbdc is an open source headers only C++ framework and library built on top of various real-world tested lockfree algorithms that facilit

A geometry dash modding sdk that contains cocos2d headers

Adrikikicp-SDK GD SDK that i use for my mods What is the meaning of SDK???? SDK is Software Development Kit. This is a GD modding sdk that i use for m

A Tcp/Ip stack implementation on top of Solarflare ef_vi, and a C++ headers only framework for tcp multiplexing client/server.

Efvitcp Efvitcp is a tcp library using Solarflare ef_vi interface on linux, and also a tcp multiplexing framework for both C++ client and server progr

A set of useful C headers.

headers Summary A set of useful C headers. License This project's license is GPL 2 (as of June 1991). The whole license text can be found in LICENSE i

Decode and Print Kadena Chainweb Block Headers

decode-header - Decode and Print Kadena Chainweb BlockHeaders The tool reads Kadena Chainweb Headers in various formats from stdin and prints a JSON r

A tool that analyzes headers and generates introspection code

A tool that analyzes headers and generates introspection code

Comments
  • Add support for libc++ #1

    Add support for libc++ #1

    This PR defines

    _LIBCPP_BEGIN_NAMESPACE_STD
    _LIBCPP_END_NAMESPACE_STD
    

    macros for libc++.

    I tested this on linux with clang 8 and with gcc-9. I am not sure if it works on Windows or on MacOS.

    opened by meisam 0
  • Add support for libc++

    Add support for libc++

    Currently cpp-std-fwd does not support LLVM's libc++. Specifically, clang -stdlib=libc++ ... does not work. This is mostly because libc++ uses dedicated macros to mark the start and the end of the std namespace:

    _LIBCPP_BEGIN_NAMESPACE_STD
    _LIBCPP_END_NAMESPACE_STD
    
    opened by meisam 0
Owner
Philip Trettner
Philip Trettner
cpp-progressbar is a small console program I wrote in c++. 3 themes are available

cpp-progressbar cpp-progressbar is a small console program I wrote in c++. 3 themes are available (this program only works on linux) Instalation Downl

Zielino 3 Jun 17, 2022
A wrapper of C++ std::vector for functional programming

Say hello to functional C++ vectors A wrapper for C++ std::vector geared towards functional programming and fluent APIs. The primary focus is readabil

null 19 Jul 26, 2022
A dynamic array similar to std::vector

Vector [] vector is a dynamic array implemented using c++ and it has almost all the features of std::vector including iterators. Usage can be used in

Tanish Porwal 1 Dec 21, 2021
C++ functions matching the interface and behavior of python string methods with std::string

Pystring is a collection of C++ functions which match the interface and behavior of python's string class methods using std::string. Implemented in C+

Sony Pictures Imageworks 761 Nov 18, 2022
Bitset Sort, a faster std::sort replacement.

Bitset Sort Bitset Sort is a variant of quick sort, specifically BlockQuickSort. Bitset Sort uses a carefully written partition function to let the co

null 65 Oct 15, 2022
­čŹŽIceCream-Cpp is a little (single header) library to help with the print debugging on C++11 and forward.

??IceCream-Cpp is a little (single header) library to help with the print debugging on C++11 and forward.

Renato Garcia 409 Nov 1, 2022
A tool for generating cross-language type declarations and interface bindings.

Djinni Djinni is a tool for generating cross-language type declarations and interface bindings. It's designed to connect C++ with either Java or Objec

Dropbox 2.8k Nov 19, 2022
A reliable and easy to use CPP program header file for simplifying, code writing in cpp

CPP Custom Header This header file main purpose is to implement most famous and most used algorithm that are easy to implement but quite lengthy and t

Jitesh Kumar 1 Dec 22, 2021
Cpp-btree - Git mirror of the official (mercurial) repository of cpp-btree

This library is a C++ template library and, as such, there is no library to build and install. Copy the .h files and use them! See http://code.googl

Algorithm Ninja 62 Oct 14, 2022
Arcana.cpp - Arcana.cpp is a collection of helpers and utility code for low overhead, cross platform C++ implementation of task-based asynchrony.

Arcana.cpp Arcana is a collection of general purpose C++ utilities with no code that is specific to a particular project or specialized technology are

Microsoft 67 Nov 23, 2022