Skip to content

Commit

Permalink
[WIP] Selectors accept actual compile-time strings
Browse files Browse the repository at this point in the history
  • Loading branch information
ldionne committed Feb 11, 2018
1 parent d7abeb7 commit 8d17a59
Show file tree
Hide file tree
Showing 14 changed files with 78 additions and 35 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -495,7 +495,7 @@ struct drawable {
private:
using Storage = dyno::sbo_storage<16>;
using VTable = dyno::vtable<
dyno::local<dyno::only<decltype("draw"_s)>>,
dyno::local<dyno::only<"draw"_s>>,
dyno::remote<dyno::everything_else>
>;
dyno::poly<Drawable, Storage, VTable> poly_;
Expand Down
4 changes: 1 addition & 3 deletions benchmark/any_iterator/dyno_generic.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,7 @@ namespace dyno_generic {
int,
dyno::local_storage<16>,
dyno::vtable<
dyno::local<dyno::only<decltype("increment"_s),
decltype("dereference"_s),
decltype("equal"_s)>>,
dyno::local<dyno::only<"increment"_s, "dereference"_s, "equal"_s>>,
dyno::remote<dyno::everything_else>
>
>;
Expand Down
6 changes: 3 additions & 3 deletions benchmark/vtable/dispatch.2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ static void BM_dispatch2(benchmark::State& state) {
}
}

template <typename ...InlineMethods>
template <char const* ...InlineMethods>
using inline_only = dyno::vtable<
dyno::local<dyno::only<InlineMethods...>>,
dyno::remote<dyno::everything_else>
Expand All @@ -36,6 +36,6 @@ using inline_only = dyno::vtable<
static constexpr int N = 100;
BENCHMARK_TEMPLATE(BM_dispatch2, inheritance_tag)->Arg(N);
BENCHMARK_TEMPLATE(BM_dispatch2, inline_only<>)->Arg(N);
BENCHMARK_TEMPLATE(BM_dispatch2, inline_only<decltype("f1"_s)>)->Arg(N);
BENCHMARK_TEMPLATE(BM_dispatch2, inline_only<decltype("f1"_s), decltype("f2"_s)>)->Arg(N);
BENCHMARK_TEMPLATE(BM_dispatch2, inline_only<"f1"_s>)->Arg(N);
BENCHMARK_TEMPLATE(BM_dispatch2, inline_only<"f1"_s, "f2"_s>)->Arg(N);
BENCHMARK_MAIN();
8 changes: 4 additions & 4 deletions benchmark/vtable/dispatch.3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ static void BM_dispatch3(benchmark::State& state) {
}
}

template <typename ...InlineMethods>
template <char const* ...InlineMethods>
using inline_only = dyno::vtable<
dyno::local<dyno::only<InlineMethods...>>,
dyno::remote<dyno::everything_else>
Expand All @@ -37,7 +37,7 @@ using inline_only = dyno::vtable<
static constexpr int N = 100;
BENCHMARK_TEMPLATE(BM_dispatch3, inheritance_tag)->Arg(N);
BENCHMARK_TEMPLATE(BM_dispatch3, inline_only<>)->Arg(N);
BENCHMARK_TEMPLATE(BM_dispatch3, inline_only<decltype("f1"_s)>)->Arg(N);
BENCHMARK_TEMPLATE(BM_dispatch3, inline_only<decltype("f1"_s), decltype("f2"_s)>)->Arg(N);
BENCHMARK_TEMPLATE(BM_dispatch3, inline_only<decltype("f1"_s), decltype("f2"_s), decltype("f3"_s)>)->Arg(N);
BENCHMARK_TEMPLATE(BM_dispatch3, inline_only<"f1"_s>)->Arg(N);
BENCHMARK_TEMPLATE(BM_dispatch3, inline_only<"f1"_s, "f2"_s>)->Arg(N);
BENCHMARK_TEMPLATE(BM_dispatch3, inline_only<"f1"_s, "f2"_s, "f3"_s>)->Arg(N);
BENCHMARK_MAIN();
10 changes: 5 additions & 5 deletions benchmark/vtable/dispatch.4.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ static void BM_dispatch4(benchmark::State& state) {
}
}

template <typename ...InlineMethods>
template <char const* ...InlineMethods>
using inline_only = dyno::vtable<
dyno::local<dyno::only<InlineMethods...>>,
dyno::remote<dyno::everything_else>
Expand All @@ -38,8 +38,8 @@ using inline_only = dyno::vtable<
static constexpr int N = 100;
BENCHMARK_TEMPLATE(BM_dispatch4, inheritance_tag)->Arg(N);
BENCHMARK_TEMPLATE(BM_dispatch4, inline_only<>)->Arg(N);
BENCHMARK_TEMPLATE(BM_dispatch4, inline_only<decltype("f1"_s)>)->Arg(N);
BENCHMARK_TEMPLATE(BM_dispatch4, inline_only<decltype("f1"_s), decltype("f2"_s)>)->Arg(N);
BENCHMARK_TEMPLATE(BM_dispatch4, inline_only<decltype("f1"_s), decltype("f2"_s), decltype("f3"_s)>)->Arg(N);
BENCHMARK_TEMPLATE(BM_dispatch4, inline_only<decltype("f1"_s), decltype("f2"_s), decltype("f3"_s), decltype("f4"_s)>)->Arg(N);
BENCHMARK_TEMPLATE(BM_dispatch4, inline_only<"f1"_s>)->Arg(N);
BENCHMARK_TEMPLATE(BM_dispatch4, inline_only<"f1"_s, "f2"_s>)->Arg(N);
BENCHMARK_TEMPLATE(BM_dispatch4, inline_only<"f1"_s, "f2"_s, "f3"_s>)->Arg(N);
BENCHMARK_TEMPLATE(BM_dispatch4, inline_only<"f1"_s, "f2"_s, "f3"_s, "f4"_s>)->Arg(N);
BENCHMARK_MAIN();
4 changes: 1 addition & 3 deletions example/vtable_traits.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,7 @@ struct any_iterator {
using Concept = Iterator<reference>;
using Storage = dyno::remote_storage;
using VTable = dyno::vtable<
dyno::local<dyno::only<
decltype("increment"_s), decltype("equal"_s), decltype("dereference"_s)
>>,
dyno::local<dyno::only<"increment"_s, "equal"_s, "dereference"_s>>,
dyno::remote<dyno::everything_else>
>;
dyno::poly<Concept, Storage, VTable> poly_;
Expand Down
18 changes: 18 additions & 0 deletions include/dyno/detail/dsl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,9 @@ namespace detail {
return detail::delayed_call<string, Args&&...>{std::forward<Args>(args)...};
}

static constexpr char storage_[] = {c..., '\0'};
constexpr operator char const*() const { return storage_; }

using hana_tag = typename boost::hana::tag_of<boost::hana::string<c...>>::type;
};

Expand All @@ -115,6 +118,21 @@ namespace detail {
constexpr auto prepare_string(S) {
return detail::prepare_string_impl<S>(std::make_index_sequence<S::size()>{});
}

constexpr std::size_t constexpr_strlen(char const* s) {
std::size_t len = 0;
while (*s++ != '\0') ++len;
return len;
}

template <char const* s>
constexpr auto make_string() {
struct tmp {
static constexpr std::size_t size() { return detail::constexpr_strlen(s); }
static constexpr char const* get() { return s; }
};
return detail::prepare_string(tmp{});
}
} // end namespace detail

inline namespace literals {
Expand Down
21 changes: 11 additions & 10 deletions include/dyno/vtable.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#define DYNO_VTABLE_HPP

#include <dyno/concept.hpp>
#include <dyno/detail/dsl.hpp>
#include <dyno/detail/erase_function.hpp>
#include <dyno/detail/erase_signature.hpp>

Expand Down Expand Up @@ -208,11 +209,11 @@ struct joined_vtable {

//////////////////////////////////////////////////////////////////////////////
// Selectors
template <typename ...Functions>
template <char const* ...Functions>
struct only {
template <typename All>
constexpr auto operator()(All all) const {
auto matched = boost::hana::make_set(Functions{}...);
auto matched = boost::hana::make_set(detail::make_string<Functions>()...);
static_assert(decltype(boost::hana::is_subset(matched, all))::value,
"dyno::only: Some functions specified in this selector are not part of "
"the concept to which the selector was applied.");
Expand All @@ -223,11 +224,11 @@ struct only {
}
};

template <typename ...Functions>
template <char const* ...Functions>
struct except {
template <typename All>
constexpr auto operator()(All all) const {
auto not_matched = boost::hana::make_set(Functions{}...);
auto not_matched = boost::hana::make_set(detail::make_string<Functions>()...);
static_assert(decltype(boost::hana::is_subset(not_matched, all))::value,
"dyno::except: Some functions specified in this selector are not part of "
"the concept to which the selector was applied.");
Expand All @@ -251,12 +252,12 @@ namespace detail {
template <typename T>
struct is_valid_selector : boost::hana::false_ { };

template <typename ...Methods>
template <char const* ...Methods>
struct is_valid_selector<dyno::only<Methods...>>
: boost::hana::true_
{ };

template <typename ...Methods>
template <char const* ...Methods>
struct is_valid_selector<dyno::except<Methods...>>
: boost::hana::true_
{ };
Expand Down Expand Up @@ -389,12 +390,12 @@ constexpr auto generate_vtable(Policies policies) {
// cumbersome. Selectors provided by the library are:
//
// dyno::only<functions...>
// Picks only the specified functions from a concept. `functions` must be
// compile-time strings, such as `dyno::only<decltype("foo"_s), decltype("bar"_s)>`.
// Picks only the specified functions from a concept. `functions...` must
// be compile-time strings, such as `dyno::only<"foo"_s, "bar"_s>`.
//
// dyno::except<functions...>
// Picks all but the specified functions from a concept. `functions` must
// be compile-time strings, such as `dyno::except<decltype("foo"_s), decltype("bar"_s)>`.
// Picks all but the specified functions from a concept. `functions...`
// must be compile-time strings, such as `dyno::except<"foo"_s, "bar"_s>`.
//
// dyno::everything
// Picks all the functions from a concept.
Expand Down
28 changes: 28 additions & 0 deletions test/detail/dsl.make_string.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Copyright Louis Dionne 2017
// 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 <dyno/detail/dsl.hpp>

#include <type_traits>


int main() {
{
static constexpr char const s[] = "";
static_assert(std::is_same<decltype(dyno::detail::make_string<s>()),
dyno::detail::string<>>{});
}

{
static constexpr char const s[] = "a";
static_assert(std::is_same<decltype(dyno::detail::make_string<s>()),
dyno::detail::string<'a'>>{});
}

{
static constexpr char const s[] = "abc";
static_assert(std::is_same<decltype(dyno::detail::make_string<s>()),
dyno::detail::string<'a', 'b', 'c'>>{});
}
}
4 changes: 2 additions & 2 deletions test/vtable.fail.1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ auto dyno::concept_map<Fooable, int> = dyno::make_concept_map(

int main() {
using VTable = dyno::vtable<
dyno::local<dyno::only<decltype("a"_s)>>,
dyno::remote<dyno::only<decltype("b"_s)>>
dyno::local<dyno::only<"a"_s>>,
dyno::remote<dyno::only<"b"_s>>
>;
VTable::apply<Fooable> vtable{
dyno::complete_concept_map<Fooable, int>(dyno::concept_map<Fooable, int>)
Expand Down
2 changes: 1 addition & 1 deletion test/vtable.fail.3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,5 @@ int main() {
auto complete = dyno::complete_concept_map<Concept, Foo>(dyno::concept_map<Concept, Foo>);

// MESSAGE[The policies specified in the vtable did not fully cover all the functions provided by the concept]
dyno::vtable<dyno::local<dyno::only<decltype("f"_s)>>>::apply<Concept> vtable{complete};
dyno::vtable<dyno::local<dyno::only<"f"_s>>>::apply<Concept> vtable{complete};
}
2 changes: 1 addition & 1 deletion test/vtable.fail.4.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ int main() {

// MESSAGE[Some functions specified in this selector are not part of the concept to which the selector was applied]
dyno::vtable<
dyno::local<dyno::only<decltype("nonexistent"_s)>>,
dyno::local<dyno::only<"nonexistent"_s>>,
dyno::remote<dyno::everything_else>
>::apply<Concept> vtable{complete};
}
2 changes: 1 addition & 1 deletion test/vtable.fail.5.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ int main() {

// MESSAGE[Some functions specified in this selector are not part of the concept to which the selector was applied]
dyno::vtable<
dyno::local<dyno::except<decltype("nonexistent"_s)>>,
dyno::local<dyno::except<"nonexistent"_s>>,
dyno::remote<dyno::everything_else>
>::apply<Concept> vtable{complete};
}
2 changes: 1 addition & 1 deletion test/vtable.selector.fail.2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ int main() {

// MESSAGE[dyno::remote: Provided invalid selector. Valid selectors are]
dyno::vtable<
dyno::local<dyno::only<decltype("f"_s)>>,
dyno::local<dyno::only<"f"_s>>,
dyno::remote<struct inexistent>
>::apply<Concept> vtable{complete};
}

0 comments on commit 8d17a59

Please sign in to comment.