<commit_before>#ifndef APOLLO_CONVERTERS_HPP_INCLUDED
#define APOLLO_CONVERTERS_HPP_INCLUDED APOLLO_CONVERTERS_HPP_INCLUDED

#include <apollo/converters_fwd.hpp>
#include <apollo/error.hpp>
#include <apollo/detail/meta_util.hpp>

#include <boost/exception/errinfo_type_info_name.hpp>
#include <boost/exception/info.hpp>
#include <boost/throw_exception.hpp>
#include <lua.hpp>

#include <type_traits>

namespace apollo {

struct raw_function;

template <typename Converter>
using to_type_of = typename detail::remove_qualifiers<Converter>::type::to_type;


namespace detail {
// Lua type constants //

template <typename T, typename Enable=void> // Default to userdata.
struct lua_type_id: std::integral_constant<int, LUA_TUSERDATA> {};

template <typename T> // Any arithmetic type except bool is a number.
struct lua_type_id<T,
        typename std::enable_if<
            std::is_same<T, typename detail::remove_qualifiers<T>::type>::value
            && std::is_arithmetic<T>::value>::type>
        : std::integral_constant<int, LUA_TNUMBER> {};

template <> // boolean
struct lua_type_id<bool>: std::integral_constant<int, LUA_TBOOLEAN> {};

template <> struct lua_type_id<void>: std::integral_constant<int, LUA_TNIL> {};

// string
template <>
struct lua_type_id<char*>: std::integral_constant<int, LUA_TSTRING> {};
template <> struct lua_type_id<char const*>: lua_type_id<char*> {};
template <> struct lua_type_id<char>: lua_type_id<char*> {};
template <std::size_t N> struct lua_type_id<char[N]>: lua_type_id<char*> {};
template <> struct lua_type_id<std::string>: lua_type_id<char*> {};


template <> // thread (lua_State*)
struct lua_type_id<lua_State*>: std::integral_constant<int, LUA_TTHREAD> {};

template <typename T>
struct is_plain_function: std::integral_constant<bool,
        std::is_function<typename std::remove_pointer<T>::type>::value>
{ };

// function (plain function (pointer), boost and std function templates)
template <typename T>
struct lua_type_id<T,
        typename std::enable_if<
        detail::is_plain_function<T>::value ||
        std::is_member_function_pointer<T>::value>::type>
    : std::integral_constant<int, LUA_TFUNCTION> {};

template <template <class> class FObj, typename R, typename... Args>
struct lua_type_id<FObj<R(Args...)>>
    : std::integral_constant<int, LUA_TFUNCTION> {};

template <> struct lua_type_id<raw_function>
    : std::integral_constant<int, LUA_TFUNCTION> {};

} // namespace detail

// Const references to primitive types are handled as non-references.
template<typename T>
struct converter<T, typename std::enable_if<
    detail::is_const_reference<T>::value &&
    detail::lua_type_id<typename detail::remove_qualifiers<T>::type>::value
     != LUA_TUSERDATA>::type
>: converter<typename detail::remove_qualifiers<T>::type>
{};

template <typename T>
using push_converter_for = converter<
    typename detail::remove_qualifiers<T>::type>;

template <typename T>
using pull_converter_for = converter<typename std::remove_cv<T>::type>;

namespace detail {

inline void push_impl(lua_State*)
{ }

template <typename Head, typename... Tail>
void push_impl(lua_State* L, Head&& head, Tail&&... tail)
{
    push_converter_for<Head>::push(
        L, std::forward<Head>(head));
    push_impl(L, std::forward<Tail>(tail)...);
}

} // namespace detail


template <typename T, typename... MoreTs>
void push(lua_State* L, T&& v, MoreTs&&... more)<commit_msg>Add convert_cref_by_val trait.<commit_after>#ifndef APOLLO_CONVERTERS_HPP_INCLUDED
#define APOLLO_CONVERTERS_HPP_INCLUDED APOLLO_CONVERTERS_HPP_INCLUDED

#include <apollo/converters_fwd.hpp>
#include <apollo/error.hpp>
#include <apollo/detail/meta_util.hpp>

#include <boost/exception/errinfo_type_info_name.hpp>
#include <boost/exception/info.hpp>
#include <boost/throw_exception.hpp>
#include <lua.hpp>

#include <type_traits>

namespace apollo {

struct raw_function;

template <typename Converter>
using to_type_of = typename detail::remove_qualifiers<Converter>::type::to_type;


namespace detail {
// Lua type constants //

template <typename T, typename Enable=void> // Default to userdata.
struct lua_type_id: std::integral_constant<int, LUA_TUSERDATA> {};

template <typename T> // Any arithmetic type except bool is a number.
struct lua_type_id<T,
        typename std::enable_if<
            std::is_same<T, typename detail::remove_qualifiers<T>::type>::value
            && std::is_arithmetic<T>::value>::type>
        : std::integral_constant<int, LUA_TNUMBER> {};

template <> // boolean
struct lua_type_id<bool>: std::integral_constant<int, LUA_TBOOLEAN> {};

template <> struct lua_type_id<void>: std::integral_constant<int, LUA_TNIL> {};

// string
template <>
struct lua_type_id<char*>: std::integral_constant<int, LUA_TSTRING> {};
template <> struct lua_type_id<char const*>: lua_type_id<char*> {};
template <> struct lua_type_id<char>: lua_type_id<char*> {};
template <std::size_t N> struct lua_type_id<char[N]>: lua_type_id<char*> {};
template <> struct lua_type_id<std::string>: lua_type_id<char*> {};


template <> // thread (lua_State*)
struct lua_type_id<lua_State*>: std::integral_constant<int, LUA_TTHREAD> {};

template <typename T>
struct is_plain_function: std::integral_constant<bool,
        std::is_function<typename std::remove_pointer<T>::type>::value>
{ };

// function (plain function (pointer), boost and std function templates)
template <typename T>
struct lua_type_id<T,
        typename std::enable_if<
        detail::is_plain_function<T>::value ||
        std::is_member_function_pointer<T>::value>::type>
    : std::integral_constant<int, LUA_TFUNCTION> {};

template <template <class> class FObj, typename R, typename... Args>
struct lua_type_id<FObj<R(Args...)>>
    : std::integral_constant<int, LUA_TFUNCTION> {};

template <> struct lua_type_id<raw_function>
    : std::integral_constant<int, LUA_TFUNCTION> {};

} // namespace detail

template <typename T, typename Enable=void>
struct convert_cref_by_val: std::integral_constant<bool,
    detail::lua_type_id<T>::value != LUA_TUSERDATA>
{};

// Const references to primitive types are handled as non-references.
template<typename T>
struct converter<T, typename std::enable_if<
        detail::is_const_reference<T>::value &&
        convert_cref_by_val<typename detail::remove_qualifiers<T>::type>::value
    >::type
>: converter<typename detail::remove_qualifiers<T>::type>
{};

template <typename T>
using push_converter_for = converter<
    typename detail::remove_qualifiers<T>::type>;

template <typename T>
using pull_converter_for = converter<typename std::remove_cv<T>::type>;

namespace detail {

inline void push_impl(lua_State*)
{ }

template <typename Head, typename... Tail>
void push_impl(lua_State* L, Head&& head, Tail&&... tail)
{
    push_converter_for<Head>::push(
        L, std::forward<Head>(head));
    push_impl(L, std::forward<Tail>(tail)...);
}

} // namespace detail


template <typename T, typename... MoreTs>
void push(lua_State* L, T&& v, MoreTs&&... more)
{'fraction_non_alphanumeric': 0.14293865905848788, 'fraction_numerical': 0.0, 'mean_word_length': 5.866797257590598, 'pattern_counts': {'":': 0, '<': 166, '<?xml version=': 0, '>': 166, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4413910', 'n_tokens_mistral': 2415, 'n_tokens_neox': 2296, 'n_words': 477}