I have read some companies interviews and some folks say interviewers don't allow them to use stl. Is that true? Do we have to do everything on our own? I will much appreciate if you share your experience.
Meta-Programming is one of the C++ super-powers
Traditional meta-programming model in C++ is very powerful but not the easiest to understand. Mainly because it has different syntax than 'normal' C++ with a lot of angle brackets, it's functional, immutable, etc.
There are some great template meta-programming libraries available such as boost.mp11 - which make template meta-programming much easier, but the question still remains - can we make meta-programming simpler/closer to 'normal' C++? And if so, what are the trade-offs? All in all, wouldn't be great to be able to write the same code for run-time and compile-time and/or debug compile-time code at run-time?
Reflection for C++ - - introduced a new meta-programming model which is value/consteval based and can greatly improve the experience. Together with reflection is a very powerful combination but it also has its own set of trade-offs such as slower compilation-times and some syntax/API quirks but nothing major. It's likely to be part of C++26 but is there anything we can do in the meantime to improve meta-programming experience?
That's where mp
- comes in handy - C++20 (msvc, gcc, clang) meta-programming library which supports meta-programming model similar to P2996 with a bit faster compilation times and very simplistic API. Most importantly, though, mp
makes meta-programming as close to the 'normal' C++ as possible. In the mp
world there is no difference between run-time and compile-time, the whole standard library can be leveraged including ranges. It also has reflection integration using C++20 - . Of course it has its own set of trade-offs but, IMHO, it has a lot of potential and it's super fan!
-
Note: Most of the
mp
API can work with C++17.
Example (API)
// mp::meta static_assert(mp::meta<int> == mp::meta<int>); static_assert(mp::meta<int> != mp::meta<void>); static_assert(typeid(mp::meta<int>) == typeid(mp::meta<void>)); // mp::type_of constexpr mp::info meta = mp::meta<int>; mp::type_of<meta> i{}; // same as int i{}; mp::type_of<mp::meta<bool>> b = true; // same as bool b = true; // mp::apply template<class...> struct type_list{ }; static_assert(std::is_same_v<type_list<int, int>, mp::apply_t<type_list, mp::array{meta, meta}>>); // mp::invoke static_assert(not mp::invoke<std::is_const>(meta)); static_assert(std::is_same_v<const int, mp::type_of<mp::invoke<std::add_const>(meta)>>); // hello world template<size_t N, class... Ts> using at_c = mp::type_of<std::array{mp::meta<Ts>...}[N]>; static_assert(std::is_same_v<int, at_c<0, int, bool, float>>); static_assert(std::is_same_v<bool, at_c<1, int, bool, float>>); static_assert(std::is_same_v<float, at_c<2, int, bool, float>>); // ranges template<class... Ts> constexpr mp::vector ranges = std::array{mp::meta<Ts>...} | std::views::drop(1) | std::views::reverse | std::views::filter([](auto m) { return mp::invoke<std::is_integral>(m); }) | std::views::transform([](auto m) { return mp::invoke<std::add_const>(m); }) | std::views::take(2) ; static_assert(std::is_same_v< std::variant<const int, const short>, mp::apply_t<std::variant, ranges<double, void, const short, int>> >); // reflection (requires https://github.com/boost-ext/reflect) struct foo { int a; bool b; float c; }; foo f{.a = 42, .b = true, .c = 3.2f}; constexpr mp::vector v = reflexpr(f) | std::views::filter([&](auto meta) { return member_name(meta, f) != "b"; }) ; static_assert(std::tuple{42, 3.2f} == unreflexpr<std::tuple, v>(f));
Full example - standalone -
Full example - reflection -
Library -
Supported compilers -
Compilation times benchmark -
P2996 (C++26*) | mp (C++20) |
---|---|
^T
|
meta<T>
|
typename [: T :]
|
type_of<T>
|
template for ()
|
for_each
|
substitute
|
apply
|
value_of<R>(reflect_invoke(^fn, {substitute(^meta, {reflect_value(m)})}))
|
invoke(fn, m)
|
Updates -
This month the following C++ videos have been published to YouTube. A new post will be made each week as more videos are released
ACCU Conference
07/08/2024 - 07/14/2024
-
Amplifying Black Women's Voices - Building Inclusive Tech Spaces Beyond Tokenism - Yemi Adenekan -
-
Shaping Perception - The Evolution of 3D Graphics and Cultural Transformation - Ben Kyd -
-
Gamification - Falling Down the Leader Board? - Char Ryder -
07/01/2024 - 07/07/2024
-
How to Maximize the Benefits of Neurodiversity in Software Development Teams and Support Neurodivergent Developers - Dom Davis -
-
Future of Software Programming with AI Bots at Hand - Amir Kirsh -
-
Contracts for C++ - Timur Doumler -
C++Now
07/08/2024 - 07/14/2024
-
C++ Reflection - Back on Track - David Olsen -
-
C++ Coroutines at Scale - Implementation Choices at Google - Aaron Jacobs -
-
Keynote: Employing Senders & Receivers to Tame Concurrency in C++ Embedded Systems - Michael Caisse -
C++Online
07/08/2024 - 07/14/2024
-
Lightning Talk: How I Became a C++ Mentor the "Hard" Way - Paulo Chiliguano -
-
Lightning Talk: Coccinelle for C++ - Julia Lawall -
-
Lightning Talk: Disentangling The Mikado Method When Refactoring C++ Legacy Code - Phil Nash -
07/01/2024 - 07/07/2024
-
Lightning Talk: Keeping Up to LLVM IR: An Introduction to LLVM IR - Isaac David Bermudez Lara -
-
Lightning Talk: Use SIMD Pairwise Reduction in C++! - Andrew Drakeford -
-
Lightning Talk: Why False Is Less Than True in Boolean Algebra - Ben Deane -
Audio Developer Conference
07/08/2024 - 07/14/2024
-
Why You Shouldn’t Write a DAW - David Rowland -
-
Inference Engines and Audio - Harriet Drury -
-
Building an Accessible Juce App - Harry Morley -
07/01/2024 - 07/07/2024
-
Creating Ubiquitous, Composable, Performant DSP Modules - Stefano D’Angelo -
-
Running High Channel Count Audio Applications on Linux RT - Olivier Petit -
-
Odd Challenges of Using Deep Learning in Designing a Feedback Delay Network Reverb - ADC23 -
Hi everyone. I am relatively new at cpp, but I have a mini project I would like to complete if possible. I am a test lab intern at Dana inc. and was wondering if it is possible to automate the engineers test reports. My engineer mentor mentioned that it would be nice if this could be done. Currently, they use microsoft word and have a template already, but they would like an executable file where it prompts the user to input certain responses. After they submit all the responses, the program will generate the fully formatted report.
Any guidance on this would be appreciated! Thank you
This has been bothering me for a long time, and given the stalemates I've seen everywhere, I'd like to ask what the stakeholders in the community think. This is a surprisingly simple issue but affects a lot of people.
Preamble
Clang-CL is a compiler for Clang/LLVM that , on top of supporting Clang's own options.
It is not a different compiler to Clang; in fact, the clang-cl.exe
and clang.exe
binaries in the official LLVM releases are bit-identical with equal checksums. Only the file name is different. On Linux, you could rename /usr/bin/clang
to /usr/bin/clang-cl
(which incidentally might already be present, depending on the distro and package) and try to run clang-cl main.cpp
, and suddenly you have a compiler that will automatically look for (and probably fail to find) the Windows SDK and the MSVC C/C++ headers and libraries, and will target x86_64-pc-windows-msvc
(i.e. the MSVC C++ ABI) without explicitly having to specify anything†.
This behaviour may also be controlled in the command-line with --driver-mode
. You can send normal Clang into Clang-CL mode with --driver-mode=cl
. Similarly, you can force Clang to compile a file with a .c
extension as C++ with --driver-mode=g++
(and vice-versa, with gcc
).
The problem
clang
has supported C++ modules in some form since Clang 15-16, which got a lot more stable in Clang 17, and I daresay is fully usable with Clang 18 (with some minor niggles). Given the above preamble, you'd expect Clang-CL
to operate exactly the same way, which is not the case. The example for C++20 modules with Clang turns into the following with Clang-CL:
clang-cl.exe /std:c++20 .\Hello.cppm /clang:--precompile /Fo.\Hello.pcm clang-cl.exe /std:c++20 use.cpp /clang:-fmodule-file=Hello=Hello.pcm .\Hello.pcm /Fo.\Hello.out .\Hello.out Hello World!
Okay, we need ; big deal. This is alright when working off the command-line or in Makefiles (where the command-line invocation is manually specified anyway), but somehow the modern build systems—CMake and MSBuild; not entirely sure about Meson, Build2, and XMake—have collectively decided that 'Clang-CL does not support C++20 modules'.
I have opened/found the following threads/comments about the issue (the first is a year old, I can't believe it):
From what I see, discussion has stalled. There are a few options:
-
Expect and allow Clang-CL to accept Clang's
-fmodule-*
and--precompile
as first-class citizens, i.e. without/clang:
.-
This is straightforward—a handful of one-liners which .
-
This means accepting that Clang-CL's module handling is different to CL's, and accounting for this in all build systems.
-
-
Require Clang-CL (and therefore, Clang) to support MSVC's arguments, and therefore, imply that Clang emits MSVC-compatible IFCs.
-
This requires some serious mangling that will probably involve all three of the driver, front-end, and back-end.
-
However this is what many build system authors and users expect: for Clang-CL to behave exactly like CL.
-
Personally, I feel there is existing precedent for Clang-CL's behaviour to diverge from CL's, which honestly should be expected: they're different compilers, after all. For instance, link-time/whole-program/inter-procedural optimisation is handled in Clang-CL using -flto=thin
. It doesn't even have MSVC's /GL
and /LTCG
. The interim object binaries emitted are incompatible, too.
I'm inclined to believe C++ modules are a very similar situation, especially given all implementations rely deeply on compiler internals. In fact one can't even mix .pcm
files compiled by Clangs with different Git commit hashes.
I'd love to spur some discussion about this, which I daresay is one of the last few BIG issues with C++20 modules. Clang and MSVC devs, build system authors, and users, do say what you think.
† Fun fact, this setup completely obviates and is probably superior to MinGW as a Windows cross-compiler for Linux, especially if you go the full bore and mount the real MSVC headers, libraries, and Windows SDK in a case-insensitive filesystem like .
I'm reading Jason Turner's Best Practices () (no affiliation, just enjoy his content).
Anyways, from one of the chapters, he asks the reader to explain the difference between the following as an exercise:
std::array<std::shared_ptr<char>, 2> data { std::make_shared<char>(40), std::make_shared<char>(2) }; std::vector<std::shared_ptr<char>> vec { std::make_shared<char>(40), std::make_shared<char>(2) };
(Specifically, I believe he means the difference with respect to how the initializer list works // allocations).
I ran these examples on compiler explorer while overloading the `new` operator, and the results are interesting (see link below) - `vec` has an extra 32 byte allocation. Anyone understand where that comes from...?
I am working on making a large legacy codebase "module ready". My plan is to use a CMake option (e.g., -D USE_MODULES=ON
) to switch from header includes to module imports. This should require minimal changes to the current .hpp/.cpp files, and I intend to create a thin wrapper module.
I found by where she explains how she transformed the header-only fmt library to support such a dual build mode. However, I've encountered challenges applying this approach to libraries with source files (i.e., not header-only).
I've created a working solution in (particularly note the 06/
folder) and wrote a related discussing the implementation.
Has anyone else attempted something similar or found a better solution? Links to dedicated blog posts, repositories, or YouTube talks would be much appreciated.
Additionally, I would welcome any general feedback. Are there any potential pitfalls I haven't addressed yet?
EDIT: The following improvement ideas have been mentioned
-
Allow
import
s of the same library in the primary module interface and at the same time in the implementation unit. This will lead to less boilerplate (no more additional scanning needed).-
Has been implemented in .
-
-
Convert each cpp file into their own module implementation unit instead of a separate unity build type module implementation unit (possibly faster incremental build times).
-
Has been implemented in .
-
-
Make use of
import std;
if available.
Hey,
Emil Dohne is creating a modern and performant C++20 read/write parser of Photoshop Files (*.psd and *.psb) with fully fledged Python bindings hosted on PyPi, completely on its own.
I just wanted to help him out trying to make his work known, so that more people can utilize this incredibily useful repo and in order to find someone incredibly talented and kind people that wanted to help him out collaborating in the development! At the moment Emil is occupied by another project that he will end by the end of July and he will then be back 100% on this project.
I reckon that the hierarchy of new features needed/really wanted are the following:
-
Support for Smart Object Layers - replacing images inside of the smart object
-
Support for Adjustment Layers
-
Support for Vector Masks
-
Support for Text Layers
-
CMYK, Indexed, Duotone and Greyscale Color Modes
Thank you to whoever even takes the time to read this, let alone whoever shares this project and even more to incredibly smart people that will help Emil out.
Here's some more info about this project:
About
PhotoshopAPI is a C++20 Library with Python bindings for reading and writing of Photoshop Files (*.psd and *.psb) based on previous works from , and . As well as the official , where applicable. The library is continuously tested for correctness in its core functionality. If you do find a bug please submit an issue to the github page.
The motivation to create another library despite all the other works present is that there isn't a library which has layer editing as a first class citizen while also supporting all bit-depths known to Photoshop (8-bits
, 16-bits
, 32-bits
). This Library aims to create an abstraction between the raw binary file format and the structure that the user interfaces against to provide a more intuitive approach to the editing of Photoshop Files.
Why should you care?
Photoshop itself is unfortunately often slow to read/write files and the built-in tools for automatically/programmatically modifying files suffer this same issue. On top of this, due to the extensive history of the Photoshop File Format, Photoshop files written out by Photoshop itself are often unnecessarily bloated to add backwards compatibility or cross-software compatibility.
The PhotoshopAPI tries to address these issue by allowing the user to read/write/modify Photoshop Files without ever having to enter Photoshop itself which additionally means, no license is required. It is roughly 5-10x faster in reads and 20x faster in writes than photoshop while producing files that are consistently 20-50% lower in size (see the benchmarks section on readthedocs for details). The cost of parsing is paid up front either on read or on write so modifying the layer structure itself is almost instantaneous (except for adding new layers).
Features
Supported:
-
Read and write of *.psd and *.psb files
-
Creating and modifying simple and complex nested layer structures
-
Pixel Masks
-
Modifying layer attributes (name, blend mode etc.)
-
Setting the Display ICC Profile
-
Setting the DPI of the document
-
8-, 16- and 32-bit files
-
RGB Color Mode
-
All compression modes known to Photoshop
Planned:
-
Support for Smart Object Layers
-
Support for Adjustment Layers
-
Support for Vector Masks
-
Support for Text Layers
-
CMYK, Indexed, Duotone and Greyscale Color Modes
Not Supported:
-
Files written by the PhotoshopAPI do not contain a valid merged image in order to save size meaning they will not behave properly when opened in third party apps requiring these (such as Lightroom)
-
Lab and Multichannel Color Modes
Python
The PhotoshopAPI comes with fully fledged Python bindings which can be simply installed using
$ py -m pip install PhotoshopAPI
alternatively the wheels can be downloaded from the Releases page. For examples on how to use the python bindings please refer to the Python Bindings section on or check out the PhotoshopExamples/ directory on the github page which includes examples for Python as well as C++.
For an even quicker way of getting started check out the section!
Documentation
The full documentation with benchmarks, build instructions and code reference is hosted on the .
Requirements
This goes over requirements for usage, for development requirements please visit the .
-
A CPU with AVX2 support (this is most CPUs after 2014) will greatly increase performance, if we detect this to not be there we disable this optimization
-
A 64-bit system
-
C++ Library: Linux, Windows or MacOS
-
Python Library1: Linux, Windows, MacOS
The python bindings support python >=3.7 (except for ARM-based MacOS machines which raise this to >=3.10)
Performance
The PhotoshopAPI is built with performance as one of its foremost concerns. Using it should enable you to optimize your pipeline rather than slow it down. It runs fully multithreaded with SIMD instructions to leverage all the computing power your computer can afford.
As the feature set increases this will keep being one of the key requirements. For detailed benchmarks running on a variety of different configurations please visit the
Below you can find some of the benchmarks comparing the PhotoshopAPI ('PSAPI') against Photoshop in read/write performance
hi, i want to create a group where like minded programmers can talk online and collaborate on cool projects and stuff and just a general chill vibe.
i’m gonna create a discord i’m just making a post here to see who would be interested.
A current project that I am undertaking now is making a cross platform music player using C++ and Qt
Is it just me or is this extremely counter-intuitive? (taken from )
// std::greater<int> makes the max priority queue act as a min priority queue.
It's been years and I still haven't found an easy way to memorise which comparator turns a sort into an ascending and which turns it into a descending order, and this isn't making it any easier. Does anyone have a trick that makes it easier for you?
Seriously, why is this not a thing when static_assert already exists?
I'm working on a project for learning purposes, specifically a game engine. As part of this, I've been developing a logging component. After researching existing logging implementations (spdlog, Unreal Engine, O3DE, Abseil, gRPC, etc.), I noticed that many are outdated, apart from spdlog. Logging is typically one of the initial components implemented and often lacks newer features.
I'm currently using C++20 and want to understand how modern logging should be implemented. I've created two basic implementations for logging formatted output to the console:
Implementation 1: FormatLogger
#pragma once #include <format> #include <string_view> class FormatLogger { public: template<typename... Args> void log(std::string_view format, Args &&...args) { auto formatted = std::vformat(format, std::make_format_args(args...)); output(formatted); } private: void output(const std::string &message); }; void FormatLogger::output(const std::string &message) { std::cout << message << '\n'; }
Implementation 2: VAListLogger
#pragma once class VAListLogger { public: void log(const char* format, ...); private: static constexpr size_t BUFFER_SIZE = 1024; void output(const char* message); }; #include <cstdarg> #include <cstdio> void VAListLogger::log(const char *format, ...) { va_list args; va_start(args, format); char buffer[1024]; // Adjust size as needed vsnprintf(buffer, sizeof(buffer), format, args); va_end(args); output(buffer); } void VAListLogger::output(const char *message) { printf("%s\n", message); }
Performance Comparison
I conducted a simple benchmark by calling each logger 1,000,000 times, printing a formatted string with 200 characters and the value of pi. The results were as follows:
VAListLogger: 81,628 ms FormatLogger: 53,378 ms
I also built both implementations as static libraries in debug mode:
VAListLogger: 381 KB FormatLogger: 2.33 MB
The results show that while VAListLogger is smaller in binary size, it is slower. FormatLogger is faster but significantly larger.
I also read which suggests that std::format might not be suitable for game engines due to its impact on binary size and compile times in large codebases.
What else should i consider and what is recommended? (probably nothing of my attempts?)