Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Selectors accept actual compile-time strings #41

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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};
}