Boost.mpl

Joined
11/5/14
Messages
321
Points
53
I am a noob when it comes to type_traits and concepts in C++; I watched the CppCon talk by Jody Hagins and I find type metafunctions really cool. I can write simple stuff e.g. implement std::decay<T> on my own.

Is Boost.mpl/Boost.hana a superset of the features that the current C++ standard has to offer? I want to play around a bit; and was thinking of exploring it.
 
Last edited:
I would first concentrate on type_traits and Concepts in C++20 and take it from there.

BTW We discuss C++20 Concepts + examples + exercises in QN < Advanced C++ course.> :ninja:

Check out this useful stuff after that
Boost Describe
Boost PFR
Code:
#include <boost/describe.hpp>
#include <boost/mp11.hpp>
#include <cstdio>

enum class E
{
    v1 = 42,
    v2, // 43
    v3 = 5
};

BOOST_DESCRIBE_ENUM(E, v1, v2, v3)

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

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

        });
}
 
Last edited:
PFR 101
Code:
// Increment each field of the variable on 1 and
// output the content of the variable.

#include <cassert>
#include <boost/pfr.hpp>
#include <boost/type_index.hpp>
#include <iostream>

struct test {
    int f1;
    long f2;
};

test var{ 42, 43 };

boost::pfr::for_each_field(var, [](auto& field) {
    field += 1;
    });

// Outputs: {43, 44}
std::cout << boost::pfr::io(var);
 
Boost Fusion = uses STL and mpl

Choose MPL over fusion when doing pure type calculations. Once the static type calculation is finished, you can instantiate a fusion sequence (see Conversion) for the runtime part.

Code:
// TestFusion101.cpp
//
// Examples from Boost Fusion library.
//
// (C) Datasim Education BV 2016-2018
//

#include <vector>
#include <string>
#include <iostream>
#include <algorithm>                                                                                                                    
#include <boost/fusion/sequence.hpp>
#include <boost/fusion/include/sequence.hpp>
#include <boost/fusion/include/algorithm.hpp>


namespace fusion = boost::fusion;

struct Print
{
template <typename T>
    void operator()(T const& x) const
    {
        std::cout << "Name: " << typeid(x).name() << '\n';
    }
};


int main()
{
    fusion::vector<int, char, std::string> tuple(1, 'x', std::string("101"));
    int i = fusion::at_c<0>(tuple);
    char ch = fusion::at_c<1>(tuple);
    std::string s = fusion::at_c<2>(tuple);
   
    fusion::for_each(tuple, Print());

    return 0;
}
 
Last edited:
I would first concentrate on type_traits and Concepts in C++20 and take it from there.

BTW We discuss C++20 Concepts + examples + exercises in QN < Advanced C++ course.> :ninja:

Check out this useful stuff after that
Boost Describe
Boost PFR
Code:
#include <boost/describe.hpp>
#include <boost/mp11.hpp>
#include <cstdio>

enum class E
{
    v1 = 42,
    v2, // 43
    v3 = 5
};

BOOST_DESCRIBE_ENUM(E, v1, v2, v3)

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

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

        });
}
This is supercool! So, there is a whole boost::mp11::algorithm - compile-time equivalent of STL algorithms. For example, I looked at mp11::sort<L,COMP>, that performs compile-time sort.
 
I will code it up.

Btw, I read a fun quote about monads today.

Monads can be tricky to grasp at first. By the time, you've understood what it is, you'll have lost the ability to explain it to others.
 
Last edited:
I read up a bit on this -fairly straightfoward.
  • Functor F - A container for types that has a map e.g. List in F# or std::optional<T> in C++. Essentially, anything that can be mapped over.
  • map - A function that takes a function g:T ->U and creates the lifted function g':F[T] -> F[U] e.g. it takes in a function g:char->int and outputs optional<char>->optional<int>.
  • map(g) is therefore the lifted function.
 
Last edited:
I read up a bit on this -fairly straightfoward.
  • Functor F - A container for types that has a map e.g. List in F# or std::option<T> in C++. Essentially, anything that can be mapped over.
  • map - A function that takes a function g:T ->U and creates the lifted function g':F[T] -> F[U] e.g. it takes in a function g:char->int and outputs optional<char>->optional<int>.
  • map(g) is therefore the lifted function.
Professor Duffy gotta love this!
 
During undergrad in maths, most of us avoided Category like the plague.
Stay focused.
 
Anyone here who is also a fan of lambdas and variadics? This is fun, if you haven't tried before:

C++:
#include <iostream>
#include <functional>
#include <cmath>
#include <cassert>

/* curry<N>(f) is an operator form of the function of n arguments,
   so that curry<N>(f)(x_1)(x_2)...(x_n) = f(x_1,...,x_n).

   Also, curry<N>(f)(x_1) = curry<N-1>(f'(x_2,...,x_n))
   where f' is a function of (N-1) variables and the result of partial function application; 
   after binding x_1 to f.
*/

template<int N>
auto curry (auto f){
    if constexpr(N == 1){
        return [=](auto x){
            return f(x);
        };
    }else{
        return [=](auto x){
            return curry<N-1>(
                [=](auto... rest){
                    return f(x, rest...);
            });
        };
    }
};

int main()
{
    auto norm = [](double x, double y, double z) -> double {
        return sqrt(x*x + y*y + z*z);
    };

    assert(curry<3>(norm)(1)(2)(2) == 3.0);
    return 0;
}

Curry<N> function
 
Back
Top Bottom