Skip to content

Commit

Permalink
feat(Constructors): allow overloading of the same arity
Browse files Browse the repository at this point in the history
  • Loading branch information
BotellaA committed Aug 17, 2021
1 parent adf6eec commit a6b44be
Show file tree
Hide file tree
Showing 7 changed files with 2,258 additions and 1,015 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ The class can be renamed on the JavaScript side by using the `NAMED_GENEPI_CLASS
second argument. This is especially useful for binding a template class
specialization with a more reasonable name: `NAMED_GENEPI_CLASS(Data<int>, IntData)`.

Constructors are exported with a macro call `GENEPI_CONSTRUCTOR(types...);` where `types` is a comma-separated list of arguments to the constructor, such as `int, int`. Calling `GENEPI_CONSTRUCTOR` multiple times allows overloading it, but **each overload must have a different number of arguments**.
Constructors are exported with a macro call `GENEPI_CONSTRUCTOR(types...);` where `types` is a comma-separated list of arguments to the constructor, such as `int, int`. Calling `GENEPI_CONSTRUCTOR` multiple times allows overloading it.

Constructor arguments are the only types that `genepi` cannot detect automatically.

Expand Down
6 changes: 6 additions & 0 deletions examples/classes/classes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ class ClassExample
std::cout << "Ints: " << a << " " << b << std::endl;
}

ClassExample( int a )
{
std::cout << "Int: " << a << std::endl;
}

ClassExample( const std::string& msg )
{
std::cout << "String: " << msg << std::endl;
Expand All @@ -50,6 +55,7 @@ GENEPI_CLASS( ClassExample )
GENEPI_CONSTRUCTOR();
GENEPI_CONSTRUCTOR( int, int );
GENEPI_CONSTRUCTOR( const std::string& );
GENEPI_CONSTRUCTOR( int );
}

GENEPI_MODULE( classes );
3 changes: 2 additions & 1 deletion examples/classes/classes.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,5 @@ var classes = require('bindings')('genepi-classes');

var a = new classes.ClassExample();
var b = new classes.ClassExample(42, 54);
var c = new classes.ClassExample("Don't panic");
var c = new classes.ClassExample(42);
var d = new classes.ClassExample("Don't panic");
16 changes: 14 additions & 2 deletions include/genepi/bind_class.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,20 @@ namespace genepi
{
try
{
constructors_.at(
static_cast< unsigned int >( info.Length() ) )( info );
for( const auto& constructor : constructors_.at(
static_cast< unsigned int >( info.Length() ) ) )
{
try
{
constructor( info );
return;
}
catch( const Napi::Error& e )
{
continue;
}
}
throw Napi::Error::New( info.Env(), "Wrong argument types" );
}
catch( const std::out_of_range& )
{
Expand Down
5 changes: 3 additions & 2 deletions include/genepi/bind_class_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ namespace genepi
public:
void add_constructor( BaseSignature* signature )
{
constructors_[signature->arity()] = signature->caller();
constructors_[signature->arity()].emplace_back(
signature->caller() );
}

void add_static_method(
Expand Down Expand Up @@ -123,7 +124,7 @@ namespace genepi
protected:
bool is_initialized_{ false };
std::string name_;
std::map< unsigned int, Callable > constructors_;
std::map< unsigned int, std::vector< Callable > > constructors_;
std::deque< MethodDefinition > static_methods_;
std::deque< MethodDefinition > methods_;
std::deque< SuperClassSpec > super_classes_;
Expand Down
7 changes: 7 additions & 0 deletions include/genepi/signature/constructor_signature.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,16 @@ namespace genepi
using ConstructWrapper = Creator< Bound,
typename MapWithIndex< TypeList, ArgFromNapiValue, Args... >::
type >;
using Parent =
TemplatedBaseSignature< ConstructorSignature, Bound *, Args... >;

static Napi::Value call( const Napi::CallbackInfo &args )
{
if( !Parent::CheckWrapper::are_types_valid( args ) )
{
throw Napi::Error::New(
args.Env(), Parent::CheckWrapper::getTypeError( args ) );
}
ConstructWrapper::create( args );
return args.Env().Undefined();
}
Expand Down

0 comments on commit a6b44be

Please sign in to comment.