#include <functional>
#include <iostream>
#include <string>
#include <cassert>

// Call f with one argument
template <class Fn, class Arg>
auto call(const Fn &f, const Arg & arg) -> decltype(f(arg)) {
    return f(arg);
}

// Helper functor for the function below
template<class Fn1, class Fn2>
class CompFn {
    Fn1 a;
    Fn2 b;

public:
    CompFn(const Fn1 &f1, const Fn2 &f2) : a(f1), b(f2) {}

    template<class Arg> inline
    bool operator()(const Arg & arg) const { // *** "FIXED" BOOL RETURN TYPE ACCORDING TO THE TEST CASE ***
        return call(b, call(a, arg));
    }
};

/** Composition of f1 and f2 (f2 after f1). */
template<class Fn1, class Fn2>
CompFn<Fn1,Fn2> comp(const Fn1 &f1, const Fn2 &f2) {
    return CompFn<Fn1,Fn2>(f1, f2);
}



int main() {
    // Example: Take the length of the string and compare it against zero.
    std::function<int(std::string)> stringLength = [](std::string s) { return s.size(); };
    std::function<bool(int)> greaterZero = [](int x) { return x > 0; };
    auto stringNotEmpty = comp(stringLength, greaterZero);
    
    std::string testInput1 = "foo";
    std::string testInput2 = "";

    assert(call(stringNotEmpty,testInput1) == true);
    assert(call(stringNotEmpty,testInput2) == false);
}