#pragma once

#include <tuple>
#include <utility>

namespace gencpp {
namespace util {

/**
 * @brief A complex template class demonstrating variadic templates.
 */
template <typename... Args>
class MultiBuffer {
public:
    void SetData(Args... args) {
        m_data = std::make_tuple(args...);
    }

    template <size_t I>
    auto Get() const -> const typename std::tuple_element<I, std::tuple<Args...>>::type& {
        return std::get<I>(m_data);
    }

private:
    std::tuple<Args...> m_data;
};

/**
 * @brief Template specialization example.
 */
template <typename T>
struct TypeTraits {
    static constexpr bool IsPointer = false;
};

template <typename T>
struct TypeTraits<T*> {
    static constexpr bool IsPointer = true;
};

/**
 * @brief Nested template class.
 */
template <typename Outer>
struct Container {
    template <typename Inner>
    struct Wrapper {
        Inner value;
        Outer context;
    };
};

} // namespace util
} // namespace gencpp
