<commit_before>#ifndef MICROPYTHON_WRAP_DETAIL_FUNCTIONCALL_H
#define MICROPYTHON_WRAP_DETAIL_FUNCTIONCALL_H

#include <cassert>

namespace upywrap
{
  template< class Ret >
  struct DefineRetvalConverter
  {
    typedef void* (*type)( Ret );
  };

  template<>
  struct DefineRetvalConverter< void >
  {
    typedef void* (*type)();
  };

  //Base function object for instance function calls
  template< class T, class Ret, class... A >
  struct InstanceFunctionCall
  {
    typedef Ret( *func_type )( T*, A... );
    typedef Ret( *byref_func_type )( T&, A... );
    typedef Ret( *byconstref_func_type )( const T&, A... );
    typedef Ret( T::*mem_func_type )( A... );
    typedef Ret( T::*const_mem_func_type )( A... ) const;
    InstanceFunctionCall() : convert_retval( nullptr ) {}
    virtual ~InstanceFunctionCall() {}
    virtual Ret Call( T* p, A&&... ) = 0;

    //Storage for return value converter. Only used to enable converting
    //to native /types which are defined in other modules,
    //but if we don't keep this here we'd need an extra map for each type.
    //Also this makes the calling code much cleaner since we don't have to duplicate lots of code
    //for each function type (one which does take a converter and one which doesn't): now there's
    //just a single pointe to set the convertor (see ClassWrapper/FunctionWrapper)
    //and a single point to use it (see CallReturn)
    using convert_retval_type = typename DefineRetvalConverter< Ret >::type;
    convert_retval_type convert_retval;
  };
<commit_msg>Add helper for ignoring return values<commit_after>#ifndef MICROPYTHON_WRAP_DETAIL_FUNCTIONCALL_H
#define MICROPYTHON_WRAP_DETAIL_FUNCTIONCALL_H

#include <cassert>

namespace upywrap
{
  template< class Ret >
  struct DefineRetvalConverter
  {
    typedef void* (*type)( Ret );
  };

  template<>
  struct DefineRetvalConverter< void >
  {
    typedef void* (*type)();
  };

  //Return value 'converter' which ignores the C++ return value and just returns None.
  //Use to set convert_retval when the return value isn't needed and/or isn't registered,
  //instead of having to write a wrapper function. For example if your C++ function is
  //Foo& Bar();
  //and Foo is not a registered ClassWrapper this results in
  //"TypeError: Native type class Foo has not been registered" at runtime.
  //So if you don't need the return value anyway you can make a wrapper
  //void VoidVersionOfBar()
  //{
  //  Bar();
  //}
  //and register that instead, or skip that and instead just use
  //Def<Name>( Bar, upywrap::Ignore );
  template< class Ret >
  mp_obj_t Ignore( Ret&& )
  {
    return mp_const_none;
  }

  //Base function object for instance function calls
  template< class T, class Ret, class... A >
  struct InstanceFunctionCall
  {
    typedef Ret( *func_type )( T*, A... );
    typedef Ret( *byref_func_type )( T&, A... );
    typedef Ret( *byconstref_func_type )( const T&, A... );
    typedef Ret( T::*mem_func_type )( A... );
    typedef Ret( T::*const_mem_func_type )( A... ) const;
    InstanceFunctionCall() : convert_retval( nullptr ) {}
    virtual ~InstanceFunctionCall() {}
    virtual Ret Call( T* p, A&&... ) = 0;

    //Storage for return value converter. Only used to enable converting
    //to native /types which are defined in other modules,
    //but if we don't keep this here we'd need an extra map for each type.
    //Also this makes the calling code much cleaner since we don't have to duplicate lots of code
    //for each function type (one which does take a converter and one which doesn't): now there's
    //just a single pointe to set the convertor (see ClassWrapper/FunctionWrapper)
    //and a single point to use it (see CallReturn)
    using convert_retval_type = typename DefineRetvalConverter< Ret >::type;
    convert_retval_type convert_retval;
  };

{'fraction_non_alphanumeric': 0.10378096479791395, 'fraction_numerical': 0.0005215123859191656, 'mean_word_length': 3.3541430192962545, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 17, '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': '75757', 'n_tokens_mistral': 1174, 'n_tokens_neox': 1129, 'n_words': 450}