Blog: Articles on C++11 and Computational Finance (by Daniel J. Duffy)

Visual Studio 2022 does not suppport Gaussian integers.
... not end of world, stilll, error messages are scary for some.

Gaussian integer - Wikipedia
Code: Select all
// Not on VS2022
// std::complex<int> com(1, 1);
// std::complex<int> com2(1.0, 1);
// std::complex<float> com3(1.0, 1);
std::complex<float> com3(1.0, 2.0);
 
Code:
// Copyright 2020 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt

#include <boost/describe.hpp>
#include <boost/mp11.hpp>

template<class E> char const * enum_to_string( E e )
{
    char const * r = "(unnamed)";

    boost::mp11::mp_for_each< boost::describe::describe_enumerators<E> >([&](auto D){

        if( e == D.value ) r = D.name;

    });

    return r;
}

#include <iostream>

enum E
{
    v1 = 3,
    v2,
    v3 = 13
};

BOOST_DESCRIBE_ENUM(E, v1, v2, v3)

int main()
{
    std::cout << "E(" << v1 << "): " << enum_to_string( v1 ) << std::endl;
    std::cout << "E(" << 0 << "): " << enum_to_string( E(0) ) << std::endl;

    boost::mp11::mp_for_each< boost::describe::describe_enumerators<E> >([](auto D)
    {

        std::printf("%s: %d\n", D.name, D.value);

    });
}
 
Code:
#include <iostream>
#include <string>

#include "boost/pfr.hpp"

struct some_person {
    std::string name;
    unsigned birth_year;
};

int main() {
    some_person val{ "Edgar Allan Poe", 1809 };

    std::cout << boost::pfr::get<0>(val)                // No macro!
        << " was born in " << boost::pfr::get<1>(val);  // Works with any aggregate initializables!

    std::cout << boost::pfr::io(val);                   // Outputs: {"Edgar Allan Poe", 1809}
}
 
This 3-month work was written in 2014 and rightly focused on GPUs which were hype at the time. It is now 2025, so many technical and organisational requirements have evolved and changed:


1. Code is not portable ("captive user"). Porting to CPUs => rewrite.

2. Traditional OOP used; parallel programming as an afterthought.

3. Thrust C++ library used; would it be needed now that C++20 has it all, and more.

4. Missing: a) top-down data dependency graph to find potential concurrency up front, b) portability issues: resolve by Facade and Bridge pattern.

5. GPUs only for data parallelism, not for task parallelism (only 20% used).

These are important in product development.
 

Attachments

We can avoid virtual destructor in a numbe of ways by considering other options:



1. Use smart C++11 pointers.

2. Parametric polymorphism (templates) instead of subtype polymorphism (inheritance).

3. Postpone physcal memory allocation for as long as possible (e.g. in main() using dedicated factories). Dependency Injection useful here.

3A. Fortran resolves issue by COMMON blocks. AFAIR it uses logical arrays in routines and memory allocated only in main.

4. Use stack memory (e.g. embedded systems).

5. C++ 20 Concepts (provided/required) interfaces) instead of virtual functions.

6. Avoid context-sensitive, unstable and semantically incorrect class hierarchies. Most (deep) hierarchies are not even wrong.

7. Virtual functions lead to performance hit, especially for collections of middle-sized objects.

8. Multimethods in C++20.


// The REAL is that we are using traditional inheritance + its ensuing complications.
 
Last edited:
Back
Top Bottom