10# ifndef HPP_ALIB_EXPRESSIONS_PLUGINS_CALCULUS
14# if !defined(HPP_ALIB_COMPATIBILITY_STD_BOXING_FUNCTIONAL)
21namespace alib {
namespace expressions {
namespace plugins {
31 const char* dbgCallbackName,
40 std::make_tuple( callback, resultType, cti
ALIB_DBG(, dbgCallbackName) ) );
43 "Binary operator {!Q'} already defined for types {!Q<>} (aka {})\n"
44 " and {!Q<>} (aka {}).",
50 std::make_tuple( callback, resultType, cti
ALIB_DBG(, dbgCallbackName) ) );
60 #define OP std::get<0>( *(table + i) )
61 #define LHS_TYPE std::get<1>( *(table + i) ).TypeID()
62 #define RHS_TYPE std::get<2>( *(table + i) ).TypeID()
63 #define CBFUNC std::get<3>( *(table + i) )
64 #define RESULTTYPE std::get<ALIB_REL_DBG(4,5)>( *(table + i) )
65 #define CTINVOKE std::get<ALIB_REL_DBG(5,6)>( *(table + i) )
67 for(
size_t i= 0 ; i < length ; ++i )
73 std::make_tuple( CBFUNC, RESULTTYPE, CTINVOKE
74 ALIB_DBG(, std::get<4>( *(table + i) )) ) );
77 "Binary operator {!Q'} already defined for types {!Q<>} (aka {})\n"
78 " and {!Q<>} (aka {}).",
84 std::make_tuple( CBFUNC, RESULTTYPE, CTINVOKE
85 ALIB_DBG(, std::get<4>( *(table + i) )) ) );
90 "This is rather an internal error of HashTable: The number of buckets "
91 "of hash map 'Operators' increased, although it was reserved above." )
110 "Binary operator alias {!Q'} already defined for types {!Q<>} (aka {})\n"
111 "and {!Q<>} (aka {}).",
125 #define ALIAS std::get<0>( *(table + i) )
126 #define LHS_TYPE std::get<1>( *(table + i) ).TypeID()
127 #define RHS_TYPE std::get<2>( *(table + i) ).TypeID()
128 #define OP std::get<3>( *(table + i) )
130 for(
size_t i= 0 ; i < length ; ++i )
137 "Binary operator alias {!Q'} already defined for types {!Q<>} (aka {})\n"
138 "and {!Q<>} (aka {}).",
139 ALIAS,
Cmplr.
TypeName( std::get<1>( *(table + i) ) ), LHS_TYPE,
167 ciUnaryOp.
Operator= aliasIt.Mapped();
172 auto opIt=
Operators.Find( key, hashCode );
176 auto& op= opIt.Mapped();
187 "Type mismatch in definition of unary operator {!Q} ({}) in plugin {!Q}.\n"
188 " Type specified: {!Q<>} (aka {})\n"
189 " Type returned by callback: {!Q<>} (aka {})",
192 std::get<1>(op).TypeID(),
197 ciUnaryOp.
Callback = std::get<0>(op);
212 #define OP std::get<0>( *(table + i) )
213 #define SIDE std::get<1>( *(table + i) )
214 #define CONSTVAL std::get<2>( *(table + i) )
215 #define CONSTTYPE std::get<2>( *(table + i) ).TypeID()
216 #define OTHERBOX std::get<3>( *(table + i) )
217 #define OTHERTYPE std::get<3>( *(table + i) ).TypeID()
218 #define RESULT std::get<4>( *(table + i) )
220 for(
size_t i= 0 ; i < length ; ++i )
227 "Optimization already defined for operator {!Q} with {!Lower}-hand "
228 "constant value {!Q} of type {!Q<>} (aka {}) and with "
229 "{!L}-hand type {!Q<>} (aka {}).",
263 auto aliasIt = OperatorAliases.Find( key, hashCode );
264 if( aliasIt != OperatorAliases.end() )
265 ciBinaryOp.
Operator= aliasIt.Mapped();
268 #define CBFUNC std::get<0>(op)
269 #define RESULTTYPE std::get<1>(op)
270 #define CT_INVOKABLE std::get<2>(op)
272 # define DBG_CB_NAME std::get<3>(op)
276 auto opIt = Operators.Find( key, hashCode );
277 if( opIt == Operators.end() )
280 auto& op= opIt.Mapped();
293 "Type mismatch in definition of binary operator {!Q} ({}) of plugin {!Q}.\n"
294 " Type specified: {!Q<>} (aka {})\n"
295 " Type returned by callback: {!Q<>} (aka {})",
298 RESULTTYPE .TypeID(),
314 auto entryIt= BinaryOperatorOptimizations.Find( { ciBinaryOp.
Operator,
319 if( entryIt != BinaryOperatorOptimizations.end() )
323 if( entryIt.Mapped().IsType<
void>() )
356 if( ciFunction.
QtyArgs() == 0 )
358 for(
auto& entry : ConstantIdentifiers )
360 if ( entry.Descriptor.Match( name ) )
375 ciFunction.
Name.
Reset( entry.Descriptor );
383 for(
auto& entry : Functions )
385 if( entry.Descriptor.Match( name ) )
389 size_t qtyGiven = ciFunction.
QtyArgs();
390 size_t qtyRequired = entry.SignatureLength;
391 bool isVariadic =
false;
392 if( entry.SignatureLength > 0 && ( entry.Signature[entry.SignatureLength - 1] ==
nullptr
393 || entry.Signature[entry.SignatureLength - 1]->IsType<
void>() ) )
399 size_t qtyShared = (std::min)( qtyGiven, qtyRequired );
400 bool sharedAreSameType =
true;
401 for(
size_t i= 0; i != qtyShared ; ++i )
402 sharedAreSameType&= ciFunction.
Arg(i).
IsSameType( *entry.Signature[i] );
406 if( !sharedAreSameType
407 || ( isVariadic ? qtyGiven < qtyRequired
408 : qtyGiven != qtyRequired ) )
412 Cmplr.WriteFunctionSignature( entry.Signature,
413 entry.SignatureLength,
423 && entry.Signature !=
nullptr
429 && entry.Signature ==
nullptr
437 ciFunction.
Name.
Reset( entry.Descriptor );
439 if( !entry.Callback )
454 "Type mismatch in definition of function {!Q} ({}) in plugin {!Q}.\n"
455 " Type specified: {!Q<>} (aka {})\n"
456 " Type returned by callback: {!Q<>} (aka {})",
459 entry.ResultType->TypeID(),
466 ciFunction.
Callback = entry.Callback;
488 for(
auto& entry : table )
491 if( !entry.Type.IsSameType( valueToCast ) )
495 bool operatorIsIn=
true;
496 if( entry.OperatorsAccepted !=
nullptr
497 && entry.OperatorsAccepted->size() > 0 )
500 for(
auto& op : *entry.OperatorsAccepted )
501 if( op.
Equals<false>( ciAutoCast.Operator ) )
510 && entry.OperatorsDeclined !=
nullptr
511 && entry.OperatorsDeclined->size() > 0 )
513 for(
auto& op : *entry.OperatorsDeclined )
514 if( op.
Equals<false>( ciAutoCast.Operator ) )
543 AutoCastEntry* entry= findAutoCastEntry( AutoCasts, ciAutoCast, 0 );
544 if( entry !=
nullptr )
576 entry= findAutoCastEntry( AutoCasts, ciAutoCast, 1 );
577 if( entry !=
nullptr )
bool IsSameType(const Box &other) const
const std::type_info & TypeID() const
const Placeholder & Data() const
ALIB_API NString TypeName(Type box)
#define ALIB_CALLER_NULLED
#define ALIB_WARNINGS_RESTORE
#define ALIB_WARNINGS_IGNORE_UNUSED_MACRO
#define ALIB_ASSERT_ERROR(cond,...)
#define ALIB_WARNINGS_ALLOW_UNSAFE_BUFFER_USAGE
std::vector< Box >::iterator ArgIterator
@ Equals
Verbal alias "Equals" to operator '=='.
@ AllowEmptyParenthesesForIdentifierFunctions
@ AliasEqualsOperatorWithAssignOperator
@ AllowOmittingParenthesesOfParameterlessFunctions
Box(*)(Scope &scope, ArgIterator argsBegin, ArgIterator argsEnd) CallbackDecl
@ MissingFunctionParentheses
@ IdentifierWithFunctionParentheses
@ Relative
Referring to a relative value.
@ Right
Denotes the right side of something.
@ Left
Denotes the left side of something.
lang::Exception Exception
Type alias in namespace alib.
boxing::Box Box
Type alias in namespace alib.
lang::integer integer
Type alias in namespace alib.
String ReverseCastFunctionName
const nchar * DbgCallbackNameRhs
String ReverseCastFunctionNameRhs
String & Operator
Input/Output: The binary operator symbol.
void AddFunctionsWithNonMatchingArguments(const String &signature)
String & Operator
Input/Output: The unary operator.
const nchar * DbgCallbackName
std::vector< alib::Box > Stack
static ALIB_API Box Integer
String ReverseCastFunctionName
const char * DbgCallbackName
void AddOperatorAliases(OperatorAliasTableEntry(&table)[TCapacity])
virtual ALIB_API bool TryCompilation(CIFunction &ciFunction) override
HashMap< OperatorKey, String, OperatorKey::Hash, OperatorKey::EqualTo > OperatorAliases
HashMap< BinOpOptKey, Box, BinOpOptKey::Hash, BinOpOptKey::EqualTo > BinaryOperatorOptimizations
void AddOperators(OperatorTableEntry(&table)[TCapacity])
void AddBinaryOpOptimizations(BinaryOpOptimizationsTableEntry(&table)[TCapacity])
const std::tuple< String, Type, Type, CallbackDecl, Type, CTInvokable > OperatorTableEntry
HashMap< OperatorKey, std::tuple< CallbackDecl, Box, CTInvokable ALIB_DBG(, const char *) >, OperatorKey::Hash, OperatorKey::EqualTo > Operators
void AddOperator(const String &op, Type lhsType, Type rhsType, CallbackDecl callback, const char *dbgCallbackName, Type resultType, CTInvokable cti)
const std::tuple< String, lang::Side, Type, const Box &, const Box & > BinaryOpOptimizationsTableEntry
const std::tuple< String, Type, Type, String > OperatorAliasTableEntry
void AddOperatorAlias(const String &alias, Type lhsType, Type rhsType, const String &op)
ALIB_WARNINGS_ALLOW_UNSAFE_BUFFER_USAGE constexpr integer GetInteger(int idx) const