There are some useful function objects, which can be used with mappable .

Zippers and pairers pack things into tuples and pairs respectively:

struct zipper { template<class... Args> auto operator()(Args&&... args) { return std::make_tuple(std::forward<Args>(args)...); } }; struct pairer { template<class L,class R> auto operator()(L&& l, R&& r) { return std::make_pair(std::forward<L>(l),std::forward<R>(r)); } };

If you need to pack constant values or references, you can use a variation on this concept. The pair variant is particularly useful for inserting values into std::map .

template<class... Args> struct zipper_t { template<class... Args_> auto operator()(Args_&&... args) { return std::tuple<Args...>(std::forward<Args_>(args)...); } }; template<class L,class R> struct pairer_t { template<class L_,class R_> auto operator()(L_&& l, R_&& r) { return std::pair<L,R>(std::forward<L_>(l),std::forward<R_>(r)); } };

Following the nomenclature of std::make_pair and std::make_shared , make just makes an object. This is quite useful since you can’t get a pointer to a constructor.

template<class T> struct make { template<class... Args> auto operator()(Args&&... args) { return T(std::forward<Args...>(args...)); } };

Less type strict versions of std::plus and its siblings are useful for when you need to operate on different types, such as matrices and vertices.

#define FC_BINARY_OPERATORS\ X(plus,+)\ X(minus,-)\ X(multiplies,*)\ X(divides,/)\ X(modulus,%)\ X(equal_to,==)\ X(not_equal_to,!=)\ X(greater,>)\ X(less,<)\ X(greater_equal,>=)\ X(less_equal,<=)\ X(logical_and,&&)\ X(logical_or,||)\ X(bit_and,&)\ X(bit_or,|)\ X(bit_xor,^) #define X(name,symbol)\ struct name\ {\ template<class L,class R>\ auto operator()(L&& l, R&& r)\ {\ return l symbol r;\ }\ }; FC_BINARY_OPERATORS #undef X

There also exist functions unzip and unpair which are also members of mappable analogous to the Haskell unzip. For example, unpairing a vector of tuples gives a pair of vectors:

template<class L,class R> auto unpair(std::vector<std::pair<L,R>>&& v) { std::pair<std::vector<L>,std::vector<R>> out; for (auto& p : v) { out.first.push_back(p.first); out.second.push_back(p.second); } return out; }