Skip to content

Instantly share code, notes, and snippets.

@alifahrri
Last active November 9, 2019 08:08
Show Gist options
  • Select an option

  • Save alifahrri/c538567a2774d1fd23bc6464089e3200 to your computer and use it in GitHub Desktop.

Select an option

Save alifahrri/c538567a2774d1fd23bc6464089e3200 to your computer and use it in GitHub Desktop.

Revisions

  1. alifahrri revised this gist Nov 9, 2019. 1 changed file with 16 additions and 2 deletions.
    18 changes: 16 additions & 2 deletions cpp17-traits.md
    Original file line number Diff line number Diff line change
    @@ -53,8 +53,22 @@ namespace traits {
    template <typename T>
    struct is_indexable<T, std::void_t<decltype(std::declval<T>()[size_t{}])> > : std::true_type {};

    template <typename T, typename = void>
    struct has_push_back : std::false_type {};
    template <typename T>
    struct has_push_back<T,
    std::void_t<decltype(std::declval<T>().push_back(std::declval<typename T::value_type>()))>
    : std::true_type {};

    template <typename T, typename = void>
    struct has_resize : std::false_type {};
    template <typename T>
    struct has_resize<T,
    std::void_t<decltype(std::declval<T>().resize(std::declval<typename T::size_type>()))>
    : std::true_type {};

    template <typename T>
    using is_std_array_or_vector = std::disjunction<is_std_array<std::decay_t<T>>,is_std_vector<std::decay_t<T>>>;
    } // namespace traits

    } // namespace traits
    ```
  2. alifahrri created this gist Nov 9, 2019.
    60 changes: 60 additions & 0 deletions cpp17-traits.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,60 @@
    ```C++
    namespace traits {

    template <typename T, typename = void>
    struct is_std_array : std::false_type {};
    template <typename T>
    struct is_std_array<T,std::enable_if_t<
    std::is_same_v<std::array<typename T::value_type, std::tuple_size<T>::value>, T>
    > > : std::true_type {};

    template <typename T, typename = void>
    struct is_std_vector : std::false_type {};
    template <typename T>
    struct is_std_vector<T,std::enable_if_t<
    std::is_same_v<std::vector<typename T::value_type>, T>
    > > : std::true_type {};


    template <typename T, typename ...Args>
    struct is_callable {
    private:
    template <typename F>
    static constexpr auto test(int)
    -> decltype(std::declval<F>()(std::declval<Args>()...), bool())
    { return true; }
    template <typename F>
    static constexpr auto test(char)
    { return false; }
    public:
    constexpr static bool value = test<T>(int());
    };

    /* TODO : move (?) */
    using std::begin;
    using std::end;

    template <typename T>
    struct is_iterable {
    private:
    template <typename It>
    static constexpr auto test(int)
    -> decltype(begin(std::declval<It>()), end(std::declval<It>()), bool())
    { return true; }
    template <typename It>
    static constexpr auto test(char)
    { return false; }
    public:
    constexpr static bool value = test<T>(int());
    };

    template <typename T, typename = void>
    struct is_indexable : std::false_type {};
    template <typename T>
    struct is_indexable<T, std::void_t<decltype(std::declval<T>()[size_t{}])> > : std::true_type {};

    template <typename T>
    using is_std_array_or_vector = std::disjunction<is_std_array<std::decay_t<T>>,is_std_vector<std::decay_t<T>>>;

    } // namespace traits
    ```