-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
badair
committed
May 18, 2016
1 parent
fe06094
commit 5ff3a54
Showing
7 changed files
with
525 additions
and
28 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,28 +1,3 @@ | ||
# Compiled Object files | ||
*.slo | ||
*.lo | ||
*.o | ||
*.obj | ||
|
||
# Precompiled Headers | ||
*.gch | ||
*.pch | ||
|
||
# Compiled Dynamic libraries | ||
*.so | ||
*.dylib | ||
*.dll | ||
|
||
# Fortran module files | ||
*.mod | ||
|
||
# Compiled Static libraries | ||
*.lai | ||
*.la | ||
*.a | ||
*.lib | ||
|
||
# Executables | ||
*.exe | ||
*.out | ||
*.app | ||
build*/ | ||
*.user | ||
/test/Makefile |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
|
||
# Copyright Louis Dionne 2015 | ||
# Modified Work Copyright Barrett Adair 2015 | ||
# Distributed under the Boost Software License, Version 1.0. | ||
# (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) | ||
|
||
cmake_minimum_required(VERSION 3.0) | ||
project(bind_parser CXX) | ||
enable_testing() | ||
|
||
if(BUILD_CXX_STD) | ||
else() | ||
# Defaults to C++14 if not set: | ||
set(BUILD_CXX_STD 14) | ||
endif() | ||
|
||
set (CMAKE_CXX_STANDARD ${bind_parser_CXX_STD}) | ||
|
||
# Setting up CMake options and compiler flags (more flags can be set on a per-target basis or in subdirectories) | ||
|
||
include(CheckCXXCompilerFlag) | ||
macro(bind_parser_append_flag testname flag) | ||
check_cxx_compiler_flag(${flag} ${testname}) | ||
if (${testname}) | ||
add_compile_options(${flag}) | ||
endif() | ||
endmacro() | ||
|
||
bind_parser_append_flag(bind_parser_HAS_WERROR -Werror) | ||
bind_parser_append_flag(bind_parser_HAS_WX -WX) | ||
bind_parser_append_flag(bind_parser_HAS_QUNUSED_ARGUMENTS -Qunused-arguments) | ||
bind_parser_append_flag(bind_parser_HAS_WNO_UNUSED_LOCAL_TYPEDEFS -Wno-unused-local-typedefs) | ||
bind_parser_append_flag(bind_parser_HAS_WWRITE_STRINGS -Wwrite-strings) | ||
|
||
if(MSVC AND NOT ${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang") | ||
#disable warning about symbol truncation. Doesn't matter, affected types are not linked | ||
bind_parser_append_flag(bind_parser_HAS_WD4503 -wd4503) | ||
bind_parser_append_flag(bind_parser_HAS_W3 -W3) | ||
else() | ||
bind_parser_append_flag(bind_parser_HAS_W -W) | ||
bind_parser_append_flag(bind_parser_HAS_WALL -Wall) | ||
bind_parser_append_flag(bind_parser_HAS_WEXTRA -Wextra) | ||
endif() | ||
|
||
if(NOT MSVC) | ||
bind_parser_append_flag(bind_parser_HAS_FTEMPLATE_BACKTRACE_LIMIT -ftemplate-backtrace-limit=0) | ||
bind_parser_append_flag(bind_parser_HAS_PEDANTIC -pedantic) | ||
bind_parser_append_flag(bind_parser_HAS_STDCXX1Y -std=c++1y) | ||
endif() | ||
|
||
############################################################################## | ||
# bind_parser_target_name_for(<output variable> <source file> [ext]) | ||
# Returns the target name associated to a source file. If the path of the | ||
# source file relative from the root of bind_parser is `path/to/source/file.ext`, | ||
# the target name associated to it will be `path.to.source.file`. | ||
# | ||
# The extension of the file should be specified as a last argument. If no | ||
# extension is specified, the `.cpp` extension is assumed. | ||
############################################################################## | ||
|
||
function(bind_parser_target_name_for out file) | ||
file(RELATIVE_PATH _relative ${bind_parser_SOURCE_DIR} ${file}) | ||
string(REPLACE ".cpp" "" _name ${_relative}) | ||
string(REGEX REPLACE "/" "." _name ${_name}) | ||
set(${out} "${_name}" PARENT_SCOPE) | ||
endfunction() | ||
|
||
|
||
############################################################################## | ||
# Setup the `check` target to build and then run all the tests and examples. | ||
############################################################################## | ||
|
||
add_custom_target(check | ||
COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure | ||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} | ||
COMMENT "Build and then run all the tests and examples.") | ||
|
||
add_subdirectory(test) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
|
||
# Copyright Louis Dionne 2015 | ||
# Modified Work Copyright Barrett Adair 2015 | ||
# Distributed under the Boost Software License, Version 1.0. | ||
# (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) | ||
|
||
add_custom_target(tests COMMENT "Build all the unit tests.") | ||
|
||
############################################################################## | ||
# bind_parser_add_unit_test(<name> ...) | ||
# | ||
# Equivalent to `bind_parser_add_test`, except the test is also added as a | ||
# dependency of the `tests` target. | ||
############################################################################## | ||
|
||
include_directories(${bind_parser_SOURCE_DIR}) | ||
include_directories(${CMAKE_CURRENT_LIST_DIR}) | ||
|
||
file(GLOB_RECURSE UNIT_TESTS "*.cpp") | ||
|
||
foreach(_file IN LISTS UNIT_TESTS) | ||
bind_parser_target_name_for(_target "${_file}") | ||
add_executable(${_target} EXCLUDE_FROM_ALL "${_file}") | ||
add_dependencies(tests ${_target}) | ||
add_test(${_target} ${CMAKE_CURRENT_BINARY_DIR}/${_target}) | ||
endforeach() | ||
|
||
add_dependencies(check tests) | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
/* | ||
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 | ||
|
||
#include <type_traits> | ||
#include <functional> | ||
#include <iostream> | ||
#include <sstream> | ||
#include <memory> | ||
#include <iostream> | ||
#include <cstdint> | ||
#include <cassert> | ||
|
||
#include "bind_parser.hpp" | ||
|
||
using namespace std::placeholders; | ||
|
||
struct Letter { | ||
virtual operator const char*() const volatile = 0; | ||
}; | ||
|
||
#define DEFINE_TEST_LETTER(L) \ | ||
struct L : Letter { operator const char*() const volatile override { return #L; } } | ||
|
||
DEFINE_TEST_LETTER(A); | ||
DEFINE_TEST_LETTER(B); | ||
DEFINE_TEST_LETTER(C); | ||
DEFINE_TEST_LETTER(D); | ||
DEFINE_TEST_LETTER(E); | ||
DEFINE_TEST_LETTER(F); | ||
DEFINE_TEST_LETTER(G); | ||
|
||
auto letters( | ||
const Letter& l1, | ||
const Letter& l2, | ||
const Letter& l3, | ||
const Letter& l4, | ||
const Letter& l5, | ||
const Letter& l6, | ||
const Letter& l7 | ||
) { | ||
std::stringstream ss{}; | ||
ss << l1 << l2 << l3 << l4 << l5 << l6 << l7; | ||
return ss.str(); | ||
} | ||
|
||
auto ordered_letters(A a, B b, C c, D d, E e, F f, G g) { | ||
std::stringstream ss{}; | ||
ss << a << b << c << d << e << f << g; | ||
return ss.str(); | ||
} | ||
|
||
template <typename F, typename Tuple, std::size_t... I> | ||
constexpr auto | ||
apply_helper(F&& f, Tuple&& t, std::index_sequence<I...>) { | ||
return std::forward<F>(f)(std::get<I>(std::forward<Tuple>(t))...); | ||
} | ||
|
||
template <typename F, typename Tuple> | ||
constexpr auto | ||
apply(F&& f, Tuple&& t) { | ||
return apply_helper( | ||
std::forward<F>(f), | ||
std::forward<Tuple>(t), | ||
std::make_index_sequence< | ||
std::tuple_size<std::remove_reference_t<Tuple>>::value>{} | ||
); | ||
} | ||
|
||
int main() { | ||
|
||
auto a = A{}; | ||
auto b = B{}; | ||
auto c = C{}; | ||
auto d = D{}; | ||
auto e = E{}; | ||
auto f = F{}; | ||
auto g = G{}; | ||
|
||
assert(letters(a, b, c, d, e, f, g) == "ABCDEFG"); | ||
assert(ordered_letters(a, b, c, d, e, f, g) == "ABCDEFG"); | ||
|
||
{ | ||
auto expr = bind_parser::bind(&ordered_letters, _1, _2, _3, _4, _5, _6, _7); | ||
auto test = std::bind(&ordered_letters, _1, _2, _3, _4, _5, _6, _7); | ||
using args = bind_parser::args<decltype(expr)>; | ||
using expected_args = std::tuple<A, B, C, D, E, F, G>; | ||
static_assert(std::is_same<args, expected_args>::value, ""); | ||
static_assert(std::is_same<decltype(test)&, decltype(expr.get_std_bind())>::value, ""); | ||
assert(apply(expr, expected_args{}) == "ABCDEFG"); | ||
assert(apply(test, expected_args{}) == "ABCDEFG"); | ||
} { | ||
auto expr = bind_parser::bind(&ordered_letters, a, b, c, _1, _2, _3, _4); | ||
auto test = std::bind(&ordered_letters, a, b, c, _1, _2, _3, _4); | ||
using args = bind_parser::args<decltype(expr)>; | ||
using expected_args = std::tuple<D, E, F, G>; | ||
static_assert(std::is_same<args, expected_args>::value, ""); | ||
static_assert(std::is_same<decltype(test)&, decltype(expr.get_std_bind())>::value, ""); | ||
assert(apply(test, expected_args{}) == "ABCDEFG"); | ||
assert(apply(test, expected_args{}) == "ABCDEFG"); | ||
} { | ||
auto expr = bind_parser::bind(&ordered_letters, _7, _6, _5, _4, _3, _2, _1); | ||
auto test = std::bind(&ordered_letters, _7, _6, _5, _4, _3, _2, _1); | ||
using args = bind_parser::args<decltype(expr)>; | ||
using expected_args = std::tuple<G, F, E, D, C, B, A>; | ||
static_assert(std::is_same<args, expected_args>::value, ""); | ||
static_assert(std::is_same<decltype(test)&, decltype(expr.get_std_bind())>::value, ""); | ||
assert(apply(expr, expected_args{}) == "ABCDEFG"); | ||
assert(apply(test, expected_args{}) == "ABCDEFG"); | ||
} { | ||
auto expr = bind_parser::bind(&ordered_letters, a, b, c, _4, _3, _2, _1); | ||
auto test = std::bind(&ordered_letters, a, b, c, _4, _3, _2, _1); | ||
using args = bind_parser::args<decltype(expr)>; | ||
using expected_args = std::tuple<G, F, E, D>; | ||
static_assert(std::is_same<args, expected_args>::value, ""); | ||
static_assert(std::is_same<decltype(test)&, decltype(expr.get_std_bind())>::value, ""); | ||
assert(apply(expr, expected_args{}) == "ABCDEFG"); | ||
assert(apply(test, expected_args{}) == "ABCDEFG"); | ||
} { | ||
auto expr = bind_parser::bind(&ordered_letters, _4, _3, _2, _1, e, f, g); | ||
auto test = std::bind(&ordered_letters, _4, _3, _2, _1, e, f, g); | ||
using args = bind_parser::args<decltype(expr)>; | ||
using expected_args = std::tuple<D, C, B, A>; | ||
static_assert(std::is_same<args, expected_args>::value, ""); | ||
static_assert(std::is_same<decltype(test)&, decltype(expr.get_std_bind())>::value, ""); | ||
assert(apply(expr, expected_args{}) == "ABCDEFG"); | ||
assert(apply(test, expected_args{}) == "ABCDEFG"); | ||
} { | ||
auto expr = bind_parser::bind(&letters, _1, _1, _3, _3, _2, a, b); | ||
using args = bind_parser::args<decltype(expr)>; | ||
using expected_args = std::tuple<const Letter&, const Letter&, const Letter&>; | ||
static_assert(std::is_same<args, expected_args>::value, ""); | ||
} | ||
} |
Oops, something went wrong.