Skip to content

Commit

Permalink
adding tests, make_function
Browse files Browse the repository at this point in the history
  • Loading branch information
badair committed May 25, 2016
1 parent ac90473 commit 5de2361
Show file tree
Hide file tree
Showing 5 changed files with 151 additions and 65 deletions.
50 changes: 44 additions & 6 deletions bind_parser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ Distributed under the Boost Software License, Version 1.0.
#include <utility>
#include <callable_traits/args.hpp>
#include <callable_traits/result_of.hpp>
#include <callable_traits/function_type.hpp>

namespace bind_parser {

Expand Down Expand Up @@ -824,6 +825,7 @@ namespace bind_parser {
struct bind_expression_parser
{
static constexpr const bool value = false;

using arg_types = invalid_type;
using return_type = invalid_type;
using function_type = invalid_type;
Expand Down Expand Up @@ -854,6 +856,15 @@ namespace bind_parser {
};
}

template<typename BindExpr>
using args = typename detail::bind_expression_parser<BindExpr>::args;

template<typename BindExpr>
using result_of = typename detail::bind_expression_parser<BindExpr>::return_type;

template<typename BindExpr>
using function_type = typename detail::bind_expression_parser<BindExpr>::function_type;

template<typename T, typename... Args>
inline constexpr auto
bind(T&& t, Args&&... args) ->
Expand All @@ -865,14 +876,41 @@ namespace bind_parser {
};
}

template<typename BindExpr>
using args = typename detail::bind_expression_parser<BindExpr>::args;
// make_function turns a non-overloaded callable into a type-erased std::function object
template<typename T>
inline decltype(auto) make_function(T&& t) {

template<typename BindExpr>
using result_of = typename detail::bind_expression_parser<BindExpr>::return_type;
using no_ref = typename ::std::remove_reference<T>::type;
using f = ::callable_traits::function_type<no_ref>;
return ::std::function<f>{ ::std::forward<T>(t) };
}

template<typename BindExpr>
using function_type = typename detail::bind_expression_parser<BindExpr>::function_type;
// this make_function overload turns a bind expression into a type-erased std::function object
template<typename T, typename First, typename... Others>
inline decltype(auto) make_function(T&& t, First&& first, Others&&... others) {

// bind_parser::bind is a compile-time parser of placeholder expressions,
// for the purpose of retaining more type information than std::bind normally
// allows - specifically, bind_parser::bind is used to determine the de-facto
// signature of the std::bind return type, with special considerations for
// conversions between reused placeholders and nested placeholder expressions.
// For the sake of convenience, bind_parser::bind is also a thin forwarding
// wrapper around std::bind.

using bind_expr = decltype( ::bind_parser::bind(
::std::forward<T>(t),
::std::forward<First>(first),
::std::forward<Others>(others)...
));

using f = ::bind_parser::function_type<bind_expr>;

return ::std::function<f>{ ::std::bind(
::std::forward<T>(t),
::std::forward<First>(first),
::std::forward<Others>(others)...
)};
}
}

#endif //#ifndef BIND_PARSER_HPP
36 changes: 36 additions & 0 deletions test/best_match.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
Copyright Barrett Adair 2016
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/

#include <cassert>
#include <type_traits>
#include <functional>
#include <iostream>
#include <sstream>
#include <memory>
#include <iostream>
#include <cstdint>
#include "bind_parser.hpp"

struct Vampire {};
struct Robot {};
struct Animal {};
struct Dog : Animal {};
struct Poodle : Dog {};
struct ScaryMonster : Poodle, Robot, Vampire {};

int main() {

{
using test = bind_parser::detail::best_match<
Vampire, Robot, Poodle, Animal, Dog, ScaryMonster>;

using expect = ScaryMonster;

static_assert(std::is_same<test, expect>::value, "");
}
}
68 changes: 68 additions & 0 deletions test/flatten_bind_expressions.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*
Copyright Barrett Adair 2016
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/

#include <type_traits>
#include <functional>
#include <iostream>
#include <sstream>
#include <memory>
#include <iostream>
#include <cstdint>
#include "bind_parser.hpp"

using namespace std::placeholders;

struct A {};
struct B {};
struct C {};
struct D {};
struct E {};
struct F {};
struct G {};

// functions `ordered_letters`, `BEEF_returns_D`, `BEEF_returns_G`,
// and `BEEF_returns_B` are used to set up a complex bind expression
// with bind

auto ordered_letters(A, B, C, D, E, F, G) {
return 0;
}

auto BEEF_returns_D(B, E, E, F) {
return D{};
}

auto BEEF_returns_G(B, E, E, F) {
return G{};
}

auto BEEF_returns_B(B, E, E, F) {
return B{};
}

#define INNER_3 bind_parser::bind(&BEEF_returns_B, B{}, _10, E{}, F{})
#define INNER_2 bind_parser::bind(&BEEF_returns_G, INNER_3, _9, E{}, _8)
#define INNER_1 bind_parser::bind(&BEEF_returns_D, _2, E{}, _4, _7)

int main() {

auto root = bind_parser::bind(&ordered_letters, _1, _2, _3, INNER_1, _5, _6, INNER_2);

using test = decltype(root)::flattened_bind_expressions;

using expect = std::tuple<
decltype(root),
decltype(INNER_1),
decltype(INNER_2),
decltype(INNER_3)
>;

static_assert(std::is_same<test, expect>::value, "");

return 0;
}
55 changes: 0 additions & 55 deletions test/make_function.hpp

This file was deleted.

7 changes: 3 additions & 4 deletions test/make_function_example.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,14 @@ Copyright Barrett Adair 2016
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http ://boost.org/LICENSE_1_0.txt)
->*/

#undef NDEBUG

#undef NDEBUG
#include <cassert>
#include <functional>

#include "make_function.hpp"
#include "bind_parser.hpp"

using namespace example;
using namespace bind_parser;
using namespace std::placeholders;

int add(int i, int j) {
Expand Down

0 comments on commit 5de2361

Please sign in to comment.