Skip to content

Commit

Permalink
#314: user considerations added; template operator simplifications
Browse files Browse the repository at this point in the history
  • Loading branch information
MaartenHilferink committed Sep 19, 2023
1 parent 7470b7c commit fc99e5b
Show file tree
Hide file tree
Showing 40 changed files with 245 additions and 140 deletions.
129 changes: 97 additions & 32 deletions clc/dll/include/AttrBinStruct.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

#include <functional>

#include "mci/ValueClass.h"
#include "utl/StringFunc.h"

#include "Prototypes.h"
Expand Down Expand Up @@ -140,30 +141,90 @@ void do_binary_func(
// *****************************************************************************

template <typename T>
[[noreturn]] void throwOverflow(CharPtr opName, T a, CharPtr preposition, T b)
[[noreturn]] void throwOverflow(CharPtr opName, T a, CharPtr preposition, T b, CharPtr alternativeFunc, const ValueClass* alternativeValueClass)
{
SharedStr vcName = AsString(ValueWrap<T>::GetStaticClass()->GetID());
throwDmsErrF("Numeric overflow when %1% %2% values %3% %4% %5%"
SharedStr acName;
if (alternativeValueClass)
acName = AsString(alternativeValueClass->GetID());

throwDmsErrF("Numeric overflow when %1% %2% values %3% %4% %5%;\n"
"Consider using %6% if your model deals with overflow as null values%7%%8%."
, opName, vcName.c_str(), AsString(a), preposition, AsString(b)
, alternativeFunc
, alternativeValueClass ? " or consider converting the arguments to " : ""
, alternativeValueClass ? acName.c_str() : ""
);
}

template <typename T>
template <IntegralValue T>
const ValueClass* NextAddIntegral()
{
constexpr auto nrBits = nrbits_of_v<T>;
constexpr bool isSigned = is_signed_v<T>;
switch (nrBits)
{
case 1: return ValueWrap<UInt2>::GetStaticClass();
case 2: return ValueWrap<UInt4>::GetStaticClass();
case 4: return ValueWrap<UInt8>::GetStaticClass();
case 8: return isSigned
? ValueWrap<Int16>::GetStaticClass()
: ValueWrap<UInt16>::GetStaticClass();
case 16: return isSigned
? ValueWrap<Int32>::GetStaticClass()
: ValueWrap<UInt32>::GetStaticClass();
case 32: return isSigned
? ValueWrap<Int64>::GetStaticClass()
: ValueWrap<UInt64>::GetStaticClass();
case 64: return nullptr;
default:
std::unreachable();
}
}

template <IntegralValue T>
const ValueClass* NextSubIntegral()
{
constexpr auto nrBits = nrbits_of_v<T>;
constexpr bool isSigned = is_signed_v<T>;
switch (nrBits)
{
case 1: return ValueWrap<UInt2>::GetStaticClass();
case 2: return ValueWrap<UInt4>::GetStaticClass();
case 4: return ValueWrap<Int8>::GetStaticClass();
case 8: return isSigned
? ValueWrap<Int16>::GetStaticClass()
: ValueWrap<Int8>::GetStaticClass();
case 16: return isSigned
? ValueWrap<Int32>::GetStaticClass()
: ValueWrap<Int16>::GetStaticClass();
case 32: return isSigned
? ValueWrap<Int64>::GetStaticClass()
: ValueWrap<Int32>::GetStaticClass();
case 64: return isSigned
? nullptr
: ValueWrap<Int64>::GetStaticClass();
default:
std::unreachable();
}
}

template <typename V >
struct safe_plus
{
T operator ()(T a, T b) const
V operator ()(V a, V b) const
{
T result = a + b;
if constexpr (!std::is_floating_point_v<T>)
V result = a + b;
if constexpr (!std::is_floating_point_v<V>)
{
if (!IsDefined(a))
return UNDEFINED_VALUE(T);
return UNDEFINED_VALUE(V);
if (!IsDefined(b))
return UNDEFINED_VALUE(T);
if constexpr (!is_signed_v<T>)
return UNDEFINED_VALUE(V);
if constexpr (!is_signed_v<V>)
{
if (result < a)
throwOverflow("adding", a, "and", b);
throwOverflow("adding", a, "and", b, "add_or_null", NextAddIntegral<V>());
}
else
{
Expand All @@ -174,22 +235,22 @@ struct safe_plus
{
auto resultNonnegative = (result >= 0);
if (aNonnegative !=resultNonnegative)
throwOverflow("adding", a, "and", b);
throwOverflow("adding", a, "and", b, "add_or_null", NextAddIntegral<V>());
}
}
}
return result;
}
};

template <typename T>
struct safe_plus < Point<T> >
template <typename V>
struct safe_plus < Point<V> >
{
Point<T> operator ()(Point<T> a, Point<T> b) const
Point<V> operator ()(Point<V> a, Point<V> b) const
{
return Point<T>( scalar_op(a.first, b.first), scalar_op(a.second, b.second) );
return Point<V>( scalar_op(a.first, b.first), scalar_op(a.second, b.second) );
}
safe_plus<T> scalar_op;
safe_plus<V> scalar_op;
};

template <typename T>
Expand All @@ -207,7 +268,7 @@ struct safe_minus
if constexpr (!is_signed_v<T>)
{
if (a < b)
throwOverflow("subtracting", b, "from", a);
throwOverflow("subtracting", b, "from", a, "sub_or_null", NextSubIntegral<T>());
}
else
{
Expand All @@ -218,7 +279,7 @@ struct safe_minus
{
auto resultNonnegative = (result >= 0);
if (aNonnegative != resultNonnegative)
throwOverflow("subtracting", b, "from", a);
throwOverflow("subtracting", b, "from", a, "sub_or_null", NextSubIntegral<T>());
}
}
}
Expand Down Expand Up @@ -325,61 +386,65 @@ struct safe_minus_or_null < Point<T> >
};


template <typename T> struct plus_func : std_binary_func< safe_plus<T>, T, T, T>
template <FixedSizeElement T> struct plus_func : std_binary_func< safe_plus<T>, T, T, T>
{
static ConstUnitRef unit_creator(const AbstrOperGroup* gr, const ArgSeqType& args) { return compatible_values_unit_creator_func(0, gr, args, false); }
};

template <typename T> struct minus_func: std_binary_func< safe_minus<T>, T, T, T>
template <FixedSizeElement T> struct minus_func: std_binary_func< safe_minus<T>, T, T, T>
{
static ConstUnitRef unit_creator(const AbstrOperGroup* gr, const ArgSeqType& args) { return compatible_values_unit_creator_func(0, gr, args, false); }
};

template <typename T> struct plus_or_null_func : std_binary_func< safe_plus_or_null<T>, T, T, T>
template <FixedSizeElement T> struct plus_or_null_func : std_binary_func< safe_plus_or_null<T>, T, T, T>
{
static ConstUnitRef unit_creator(const AbstrOperGroup* gr, const ArgSeqType& args) { return compatible_values_unit_creator_func(0, gr, args, false); }
};

template <typename T> struct minus_or_null_func : std_binary_func< safe_minus_or_null<T>, T, T, T>
template <FixedSizeElement T> struct minus_or_null_func : std_binary_func< safe_minus_or_null<T>, T, T, T>
{
static ConstUnitRef unit_creator(const AbstrOperGroup* gr, const ArgSeqType& args) { return compatible_values_unit_creator_func(0, gr, args, false); }
};

template <typename T> struct mul_func : binary_func<T, T, T>
template <typename V>
struct mul_func_impl : binary_func<V, V, V>
{
static ConstUnitRef unit_creator(const AbstrOperGroup* gr, const ArgSeqType& args) { return mul2_unit_creator(gr, args); }

T operator()(cref_t<T> a, cref_t<T> b) const
V operator()(cref_t<V> a, cref_t<V> b) const
{
if constexpr (!std::is_floating_point_v<T> && has_undefines_v<T>)
if constexpr (!std::is_floating_point_v<V> && has_undefines_v<V>)
{
if (!IsDefined(a) || !IsDefined(b))
return UNDEFINED_VALUE(T);
return UNDEFINED_VALUE(V);
}

T result = a * b;
V result = a * b;

if constexpr (!std::is_floating_point_v<T>)
if constexpr (!std::is_floating_point_v<V>)
{
if (a && b && b != result / a)
throwOverflow("multiplying", a, "and", b);
throwOverflow("multiplying", a, "and", b, "mul_or_null", NextAddIntegral<V>());
}

return result;
}
};

template <typename T> struct mul_func< Point<T>> : binary_func<Point<T>, Point<T>, Point<T>>
template <typename T> struct mul_func_impl<Point<T>> : binary_func<Point<T>, Point<T>, Point<T>>
{
static ConstUnitRef unit_creator(const AbstrOperGroup* gr, const ArgSeqType& args) { return mul2_unit_creator(gr, args); }

Point<T> operator ()(Point<T> a, Point<T> b) const
{
return Point<T>(scalar_op(a.first, b.first), scalar_op(a.second, b.second));
}
mul_func<T> scalar_op;
mul_func_impl<T> scalar_op;
};


template <typename T> struct mul_func : mul_func_impl<T> {};

template <typename T> struct mul_or_null_func : binary_func<T, T, T>
{
static ConstUnitRef unit_creator(const AbstrOperGroup* gr, const ArgSeqType& args) { return mul2_unit_creator(gr, args); }
Expand Down Expand Up @@ -415,7 +480,7 @@ template <typename T> struct mul_or_null_func< Point<T>> : binary_func<Point<T>,
mul_or_null_func<T> scalar_op;
};

template <typename T>
template <FixedSizeElement T>
struct mulx_func : binary_func<typename acc_type<T>::type, T, T>
{
typename mulx_func::res_type operator()(typename mulx_func::arg1_cref a1, typename mulx_func::arg2_cref a2) const
Expand Down
15 changes: 3 additions & 12 deletions clc/dll/include/OperAccUni.h
Original file line number Diff line number Diff line change
Expand Up @@ -352,20 +352,11 @@ struct OperAccPartUniDirect : FuncOperAccPartUni<TAcc1Func, OperAccPartUniWithCF
TAcc1Func m_Acc1Func;
};

template <class TAcc1Func> struct make_direct { typedef OperAccPartUniDirect <TAcc1Func> type; };
template <class TAcc1Func> struct make_buffered { typedef OperAccPartUniBuffered<TAcc1Func> type; };
template <class TAcc1Func> struct make_direct { using type = OperAccPartUniDirect <TAcc1Func>; };
template <class TAcc1Func> struct make_buffered { using type = OperAccPartUniBuffered<TAcc1Func>; };

template <class TAcc1Func> using base_of = std::conditional_t< impl::has_dms_result_type<TAcc1Func>::value, make_buffered<TAcc1Func>, make_direct<TAcc1Func> >;

template <class TAcc1Func>
struct OperAccPartUniBest: base_of<TAcc1Func>
{
OperAccPartUniBest(AbstrOperGroup* gr, const TAcc1Func& acc1Func = TAcc1Func())
: base_of<TAcc1Func>(gr, acc1Func)
{}
};


template <class TAcc1Func> using OperAccPartUniBest = typename base_of<TAcc1Func>::type;

template <typename TAcc1Func>
void CalcOperAccPartUniSer(DataWriteLock& res, const AbstrDataItem* arg1A, const AbstrDataItem* arg2A, TAcc1Func acc1Func = TAcc1Func())
Expand Down
4 changes: 2 additions & 2 deletions clc/dll/include/OperAccUniNum.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,8 @@ namespace OperAccUniNum
};

private:
tl_oper::inst_tuple<ValueTypes, OperAccTotUniNumOper <_>, AbstrOperGroup*> m_TotlAggrOpers;
tl_oper::inst_tuple<ValueTypes, OperAccPartUniNumOper<_>, AbstrOperGroup*> m_PartAggrOpers;
tl_oper::inst_tuple_templ<ValueTypes, OperAccTotUniNumOper , AbstrOperGroup*> m_TotlAggrOpers;
tl_oper::inst_tuple_templ<ValueTypes, OperAccPartUniNumOper, AbstrOperGroup*> m_PartAggrOpers;
};
}

Expand Down
6 changes: 3 additions & 3 deletions clc/dll/src/BoostBlas.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -382,9 +382,9 @@ class MatrInvOperator : public AbstrMatrInvOperator

namespace
{
tl_oper::inst_tuple<typelists::floats, MatrMulOperator<_>> matrMulOperators;
tl_oper::inst_tuple<typelists::floats, MatrVarOperator<_>> matrCovOperators;
tl_oper::inst_tuple<typelists::floats, MatrInvOperator<_>> matrInvOperators;
tl_oper::inst_tuple_templ<typelists::floats, MatrMulOperator> matrMulOperators;
tl_oper::inst_tuple_templ<typelists::floats, MatrVarOperator> matrCovOperators;
tl_oper::inst_tuple_templ<typelists::floats, MatrInvOperator> matrInvOperators;
}


Expand Down
2 changes: 1 addition & 1 deletion clc/dll/src/ClassBreak.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ namespace
ClassifyFixedOperator cfoNZJF, cfoCRJF;
};

tl_oper::inst_tuple<typelists::num_objects, ClassBreakOperators<_>> classBreakInstances;
tl_oper::inst_tuple_templ<typelists::num_objects, ClassBreakOperators> classBreakInstances;
} // end anonymous namespace

/******************************************************************************/
Expand Down
2 changes: 1 addition & 1 deletion clc/dll/src/Classify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,6 @@ struct ClassifyOperator : SearchIndexOperatorImpl<V, classify_dispatcher>

namespace
{
tl_oper::inst_tuple<typelists::numerics, ClassifyOperator<_>> classifyInstances;
tl_oper::inst_tuple_templ<typelists::numerics, ClassifyOperator> classifyInstances;
} // end anonymous namespace

8 changes: 6 additions & 2 deletions clc/dll/src/Cumulate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,9 @@ namespace Cumulate
private:
CumulateTot<UniAssigner, IniAssign> m_AggrTotlOperator;

tl_oper::inst_tuple<typelists::partition_elements, CumulatePart<UniAssigner, IniAssign, _>, AbstrOperGroup*>
template <typename T> using CumulatePartThis = CumulatePart<UniAssigner, IniAssign, T>;

tl_oper::inst_tuple_templ<typelists::partition_elements, CumulatePartThis, AbstrOperGroup*>
m_AggrPartOperator;
};

Expand All @@ -320,7 +322,9 @@ namespace Cumulate
{}

private:
tl_oper::inst_tuple<ValueTypes, CumulOperInstances<UniAssigner<_>, IniAssigner>, AbstrOperGroup*>
template <typename T> using ThisCumulOperInstances = CumulOperInstances<UniAssigner<T>, IniAssigner>;

tl_oper::inst_tuple_templ<ValueTypes, ThisCumulOperInstances, AbstrOperGroup*>
m_AggrOperators;
};

Expand Down
2 changes: 1 addition & 1 deletion clc/dll/src/ID.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ class IDOperator : public AbstrIDOperator

namespace
{
tl_oper::inst_tuple<typelists::domain_elements, IDOperator<_> >
tl_oper::inst_tuple_templ<typelists::domain_elements, IDOperator >
operInstances;
} // end anonymous namespace

Expand Down
4 changes: 2 additions & 2 deletions clc/dll/src/Index.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,6 @@ namespace
SubIndexOperator<X> m_SubIndex;
};

tl_oper::inst_tuple<typelists::fields, Operators<_> > indexOperators;
tl_oper::inst_tuple<typelists::domain_elements, OrdinalOperator <_> > ordinalOperators;
tl_oper::inst_tuple_templ<typelists::fields, Operators > indexOperators;
tl_oper::inst_tuple_templ<typelists::domain_elements, OrdinalOperator > ordinalOperators;
} // end anonymous namespace
2 changes: 1 addition & 1 deletion clc/dll/src/Invert.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,6 @@ class InvertOperator : public AbstrInvertOperator

};

tl_oper::inst_tuple<typelists::domain_elements, InvertOperators<_> > invertOperators;
tl_oper::inst_tuple_templ<typelists::domain_elements, InvertOperators > invertOperators;

} // end anonymous namespace
11 changes: 8 additions & 3 deletions clc/dll/src/OperAttrBin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -404,8 +404,13 @@ struct BinaryAttrFuncOper : BinaryAttrOper<typename BinOper::res_type, typename

template <typename TL, template <typename T> class MetaFunc>
struct BinaryInstantiation{
using OperTemplate = BinaryAttrFuncOper<MetaFunc<_> > ;
tl_oper::inst_tuple<TL, OperTemplate, AbstrOperGroup*> m_OperList;

template <typename T> struct OperTemplate : BinaryAttrFuncOper<MetaFunc<T> >
{
using BinaryAttrFuncOper<MetaFunc<T> >::BinaryAttrFuncOper; // <MetaFunc<T> >; // inherit constructors
};

tl_oper::inst_tuple_templ<TL, OperTemplate, AbstrOperGroup*> m_OperList;

BinaryInstantiation(AbstrOperGroup* gr)
: m_OperList(gr)
Expand Down Expand Up @@ -600,5 +605,5 @@ namespace {
CommonOperGroup cogStrCount("strcount");
BinaryAttrFuncOper<strcount_func> g_StrCountU(&cogStrCount);

tl_oper::inst_tuple<typelists::floats, String2Operator<_> > string2Opers;
tl_oper::inst_tuple_templ<typelists::floats, String2Operator > string2Opers;
} // namespace
4 changes: 2 additions & 2 deletions clc/dll/src/OperAttrTer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -323,8 +323,8 @@ namespace
DualTernaryAttrOperator<rgb_assign<X> > m_OperData;
};

tl_oper::inst_tuple<typelists::value_elements, iifOperator<_>> s_iifOperators;
tl_oper::inst_tuple<typelists::ints , rgbOperator<_>> s_rgbOperators;
tl_oper::inst_tuple_templ<typelists::value_elements, iifOperator> s_iifOperators;
tl_oper::inst_tuple_templ<typelists::ints , rgbOperator> s_rgbOperators;


DualTernaryAttrOperator<substr_assign3> s_subStrOperatorU (&cog_substr);
Expand Down
2 changes: 1 addition & 1 deletion clc/dll/src/OperAttrUni.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -183,5 +183,5 @@ namespace
INST(rtrim);
#undef INST

tl_oper::inst_tuple<num_objects, UnitSqrtOperator<_>, AbstrOperGroup*> g_UnitSqrtOper(&cog_sqrt);
tl_oper::inst_tuple_templ<num_objects, UnitSqrtOperator, AbstrOperGroup*> g_UnitSqrtOper(&cog_sqrt);
}
Loading

0 comments on commit fc99e5b

Please sign in to comment.