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

implement indexed_tuple with different get method #58

Merged
merged 21 commits into from
Jul 26, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
89e08ad
implement indexed_tuple with different get method
lukevalenty May 1, 2022
f94077d
workaround clang bug with base class pack
lukevalenty May 3, 2022
84fdf41
fix indexed_tuple.cpp includes
lukevalenty May 3, 2022
e09deac
replace all usage of std::tuple with indexed_tuple
lukevalenty May 3, 2022
42d73b0
replace ordered_set with indexed_tuple
lukevalenty May 3, 2022
577c1d5
cleanup tuple
lukevalenty May 3, 2022
8f96b19
make cib::detail::tuple cib::tuple
lukevalenty May 3, 2022
a151cc2
cleanup cib::tuple
lukevalenty May 3, 2022
39e8bae
multi index testcase for tuple
lukevalenty May 3, 2022
7256200
remove unused tuple_details.hpp
lukevalenty May 3, 2022
5bf4ee1
add support for cib::tuple set operations
lukevalenty May 6, 2022
1acbec3
Merge branch 'main' into bugfix/compile_performance
lukevalenty May 6, 2022
decbae3
workarounds for gcc
lukevalenty May 8, 2022
ff574bd
Merge branch 'main' into bugfix/compile_performance
lukevalenty May 8, 2022
1ed0ca7
fully qualify calls to cib::make_tuple
lukevalenty May 11, 2022
4076e03
add test case for cib::detail::name
lukevalenty May 11, 2022
e22951b
Merge branch 'main' into bugfix/compile_performance
lukevalenty Jul 26, 2022
a229d56
Merge remote-tracking branch 'origin/main' into main
lukevalenty Jul 26, 2022
ddb173e
Merge remote-tracking branch 'origin/main' into bugfix/compile_perfor…
lukevalenty Jul 26, 2022
d19c7ed
fix test case
lukevalenty Jul 26, 2022
19783f5
Merge branch 'bugfix/type_string' into bugfix/compile_performance
lukevalenty Jul 26, 2022
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
1 change: 0 additions & 1 deletion include/cib/detail/conditional.hpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#include "compiler.hpp"
#include "config_item.hpp"
#include "config_details.hpp"
#include "ordered_set.hpp"
#include "type_list.hpp"

#include <tuple>
Expand Down
1 change: 0 additions & 1 deletion include/cib/detail/config_item.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#include "compiler.hpp"
#include "ordered_set.hpp"
#include "type_list.hpp"

#include <tuple>
Expand Down
3 changes: 2 additions & 1 deletion include/cib/detail/extend.hpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "config_item.hpp"
#include "indexed_tuple.hpp"
#include "ordered_set.hpp"

#include <tuple>
Expand Down Expand Up @@ -76,7 +77,7 @@ namespace cib::detail {
(is_same_v<typename ExtensionPath::First, typename std::remove_cv_t<std::remove_reference_t<decltype(builders)>>::Service> + ... + 0) <= 1,
"Extension matched more than 1 service");

return detail::ordered_set(add(ExtensionPath{}, builders)...);
return detail::make_indexed_tuple(detail::index_metafunc_<extract_service_tag>{}, add(ExtensionPath{}, builders)...);
}, builders_tuple);
}

Expand Down
153 changes: 153 additions & 0 deletions include/cib/detail/indexed_tuple.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
#include <type_traits>
#include <utility>
#include <array>


#ifndef COMPILE_TIME_INIT_BUILD_INDEXED_TUPLE_HPP
#define COMPILE_TIME_INIT_BUILD_INDEXED_TUPLE_HPP


namespace cib::detail {
template<typename T>
struct tag_ {};

template<int Index>
struct index_ {};

template<typename T>
struct index_metafunc_ {};

template<typename T, int Index, typename... IndexTs>
struct indexed_tuple_element;

template<typename T, int Index>
struct indexed_tuple_element<T, Index> {
T value;

[[nodiscard]] constexpr T const & get(index_<Index>) const {
return value;
}
};

template<typename T, int Index, typename IndexT0>
struct indexed_tuple_element<T, Index, IndexT0> {
T value;

[[nodiscard]] constexpr T const & get(index_<Index>) const {
return value;
}

[[nodiscard]] constexpr T const & get(tag_<IndexT0>) const {
return value;
}
};

template<typename T, int Index, typename IndexT0, typename IndexT1>
struct indexed_tuple_element<T, Index, IndexT0, IndexT1> {
T value;

[[nodiscard]] constexpr T const & get(index_<Index>) const {
return value;
}

[[nodiscard]] constexpr T const & get(tag_<IndexT0>) const {
return value;
}

[[nodiscard]] constexpr T const & get(tag_<IndexT1>) const {
return value;
}
};

template<typename... IndexedTupleElementTs>
struct indexed_tuple : public IndexedTupleElementTs... {
constexpr indexed_tuple(IndexedTupleElementTs... values)
: IndexedTupleElementTs{values}...
{}

using IndexedTupleElementTs::get...;

// template<typename T>
// constexpr void get(T) const {}

[[nodiscard]] constexpr int size() const {
return sizeof...(IndexedTupleElementTs);
}
};

template<int... Indices, typename... Ts>
[[nodiscard]] constexpr auto make_indexed_tuple(std::integer_sequence<int, Indices...>, Ts const & ... values) {
return indexed_tuple{indexed_tuple_element<Ts, Indices>{values}...};
}

template<int... Indices, typename IndexMetafuncT0, typename... Ts>
[[nodiscard]] constexpr auto make_indexed_tuple(std::integer_sequence<int, Indices...>, index_metafunc_<IndexMetafuncT0>, Ts const & ... values) {
return indexed_tuple{indexed_tuple_element<Ts, Indices, typename IndexMetafuncT0::template invoke<Ts>>{values}...};
}

template<typename... Ts>
[[nodiscard]] constexpr auto make_indexed_tuple(Ts const & ... values) {
return make_indexed_tuple(std::make_integer_sequence<int, sizeof...(values)>{}, values...);
}

template<typename IndexMetafuncT0, typename... Ts>
[[nodiscard]] constexpr auto make_indexed_tuple(index_metafunc_<IndexMetafuncT0>, Ts const & ... values) {
return make_indexed_tuple(std::make_integer_sequence<int, sizeof...(values)>{}, index_metafunc_<IndexMetafuncT0>{}, values...);
}


template<typename Callable, typename... Elements>
constexpr auto apply(Callable operation, indexed_tuple<Elements...> const & t) {
return operation(t.Elements::value...);
lukevalenty marked this conversation as resolved.
Show resolved Hide resolved
}

struct indexed_tuple_pair {
unsigned int outer;
unsigned int inner;
};

template<
int... Indices,
typename... Tuples>
constexpr auto indexed_tuple_cat_impl(
std::integer_sequence<int, Indices...>,
Tuples... tuples
) {
constexpr auto num_tuples = sizeof...(tuples);
constexpr std::array<unsigned int, num_tuples> tuple_sizes{tuples.size()...};
constexpr auto element_indices = [&](){
constexpr auto total_num_elements = (tuples.size() + ...);
std::array<indexed_tuple_pair, total_num_elements> indices{};
unsigned int flat_index = 0;
for (unsigned int outer_index = 0; outer_index < num_tuples; outer_index++) {
for (unsigned int inner_index = 0; inner_index < tuple_sizes[outer_index]; inner_index++) {
indices[flat_index] = {outer_index, inner_index};
flat_index += 1;
}
}
return indices;
}();

auto const outer_tuple = make_indexed_tuple(tuples...);

return make_indexed_tuple(
outer_tuple.get(index_<element_indices[Indices].outer>{}).get(index_<element_indices[Indices].inner>{})...
);
}

template<typename... Tuples>
constexpr auto indexed_tuple_cat(Tuples... tuples) {
constexpr auto total_num_elements = (tuples.size() + ...);
return indexed_tuple_cat_impl(std::make_integer_sequence<int, total_num_elements>{}, tuples...);
}
}

namespace std {
template<typename... Values>
struct tuple_size<cib::detail::indexed_tuple<Values...>>
: std::integral_constant<std::size_t, sizeof...(Values)>
{};
}


#endif //COMPILE_TIME_INIT_BUILD_INDEXED_TUPLE_HPP
27 changes: 27 additions & 0 deletions include/cib/detail/meta.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "compiler.hpp"
#include "ordered_set.hpp"
#include "indexed_tuple.hpp"

#include <tuple>
#include <type_traits>
Expand Down Expand Up @@ -116,6 +117,20 @@ namespace cib::detail {
}, elements);
}

template<
typename... ElementTypes,
typename InitType,
typename CallableType>
[[nodiscard]] CIB_CONSTEXPR inline static auto fold_right(
indexed_tuple<ElementTypes...> const & elements,
InitType const & initial_state,
CallableType const & operation
) {
return apply([&](auto const & ... element_pack){
return (fold_helper{element_pack.value, operation} + ... + initial_state);
}, elements);
}

/**
* Perform an operation on each element of an integral sequence.
*
Expand Down Expand Up @@ -187,6 +202,18 @@ namespace cib::detail {
(operation(element_pack) , ...);
}, elements);
}

template<
typename... ElementTypes,
typename CallableType>
CIB_CONSTEXPR inline void for_each(
indexed_tuple<ElementTypes...> const & elements,
CallableType const & operation
) {
apply([&](auto const & ... element_pack){
(operation(element_pack) , ...);
}, elements);
}
}


Expand Down
20 changes: 10 additions & 10 deletions include/cib/detail/nexus_details.hpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#include "compiler.hpp"
#include "meta.hpp"
#include "type_list.hpp"
#include "ordered_set.hpp"
#include "indexed_tuple.hpp"
#include "exports.hpp"
#include "find.hpp"

Expand All @@ -11,13 +11,18 @@


namespace cib {
struct extract_service_tag {
template<typename T>
using invoke = typename T::Service;
};

template<typename ServiceBuilderList>
struct to_tuple;

template<typename... ServiceBuilders>
struct to_tuple<detail::type_list<ServiceBuilders...>> {
using type = detail::ordered_set<ServiceBuilders...>;
constexpr static inline auto value = type{ServiceBuilders{}...};
using type = decltype(detail::make_indexed_tuple(detail::index_metafunc_<extract_service_tag>{}, ServiceBuilders{}...));
constexpr static inline type value = detail::make_indexed_tuple(detail::index_metafunc_<extract_service_tag>{}, ServiceBuilders{}...);
};

template<typename ServiceBuilderList>
Expand All @@ -32,15 +37,10 @@ namespace cib {
template<typename Config>
CIB_CONSTEXPR static auto & initialized_builders_v = initialized_builders<Config>::value;

struct ServiceTagMetaFunc {
template<typename T>
using invoke = typename T::Service;
};

template<typename Config, typename RawTag>
template<typename Config, typename Tag>
struct initialized {
CIB_CONSTEXPR static auto value =
initialized_builders_v<Config>.template get<RawTag>().builder;
initialized_builders_v<Config>.template get(cib::detail::tag_<Tag>{}).builder;
};

}
Expand Down
14 changes: 7 additions & 7 deletions include/cib/detail/ordered_set.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,33 +11,33 @@

namespace cib::detail {
template<typename T>
struct tuple_element {
struct ordered_set_element {
T value;
};

template<typename... Tn>
struct ordered_set : public tuple_element<Tn>... {
struct ordered_set : public ordered_set_element<Tn>... {
constexpr ordered_set(Tn... values)
: tuple_element<Tn>{values}...
: ordered_set_element<Tn>{values}...
{}

template<int Index>
constexpr auto const & get() const {
using T = type_pack_element<Index, Tn...>;
return tuple_element<T>::value;
return ordered_set_element<T>::value;
}

template<typename T>
constexpr T const & get() const {
return tuple_element<T>::value;
return ordered_set_element<T>::value;
}

constexpr static auto size() {
return sizeof...(Tn);
}

CIB_CONSTEXPR bool operator==(ordered_set<Tn...> const & rhs) const {
return ((tuple_element<Tn>::value == rhs.tuple_element<Tn>::value) && ... && true);
return ((ordered_set_element<Tn>::value == rhs.ordered_set_element<Tn>::value) && ... && true);
}

template<typename... RhsTn>
Expand All @@ -53,7 +53,7 @@ namespace cib::detail {

template<typename Callable, typename... Values>
constexpr auto apply(Callable operation, ordered_set<Values...> const & t) {
return operation(t.tuple_element<Values>::value...);
return operation(t.ordered_set_element<Values>::value...);
}

struct index_pair {
Expand Down
8 changes: 2 additions & 6 deletions include/cib/nexus.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,11 @@ namespace cib {
private:
using this_t = nexus<Config>;

template<typename Tag>
using service_name_to_raw_type_t =
typename std::remove_const_t<std::remove_reference_t<decltype(cib::detail::find<Tag, cib::ServiceTagMetaFunc>(cib::initialized_builders_v<Config>))>>;

// Workaround unfortunate bug in clang where it can't deduce "auto" sometimes
#define CIB_BUILD_SERVICE initialized<Config, service_name_to_raw_type_t<T>>::value.template build<initialized<Config, service_name_to_raw_type_t<T>>>()
#define CIB_BUILD_SERVICE initialized<Config, Tag>::value.template build<initialized<Config, Tag>>()

public:
template<typename T>
template<typename Tag>
constexpr static decltype(CIB_BUILD_SERVICE) service = CIB_BUILD_SERVICE;
#undef CIB_BUILD_SERVICE

Expand Down
1 change: 1 addition & 0 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ add_executable(tests
callback.cpp
nexus.cpp
detail/ordered_set.cpp
detail/indexed_tuple.cpp
readme_hello_world.cpp
)

Expand Down
Loading