zorba-coders team mailing list archive
-
zorba-coders team
-
Mailing list archive
-
Message #07866
[Merge] lp:~zorba-coders/zorba/bug-966355 into lp:zorba
Paul J. Lucas has proposed merging lp:~zorba-coders/zorba/bug-966355 into lp:zorba.
Requested reviews:
Paul J. Lucas (paul-lucas)
Matthias Brantner (matthias-brantner)
Markos Zaharioudakis (markos-za)
Related bugs:
Bug #966355 in Zorba: "Compiler chooses wrong overload for some Integer operators"
https://bugs.launchpad.net/zorba/+bug/966355
For more details, see:
https://code.launchpad.net/~zorba-coders/zorba/bug-966355/+merge/102128
Added operators for built-in types (when ZORBA_WITH_BIG_INTEGER=OFF).
It turns out that the problem is harder to solve than I thought. The problem with injecting operators like:
bool operator==( IntegerImpl const&, int );
bool operator==( int, IntegerImpl const& );
// ...
into the global namespace is that a lot of ambiguity arises. According to the C++11 rules, it becomes ambiguous the compiler doesn't know whether it should convert the int to an IntegerImpl via constructor or not. (To me, it seems silly and the "obviously correct" answer *should* be not to do the conversion, but there's probably a good reason for the C++11 behavior that just not obvious to me at the moment.)
One way to fix this is to make all the constructors for IntegerImpl( T ), where T is any arithmetic type, explicit, e.g.:
explicit IntegerImpl( int = 0 );
explicit IntegerImpl( long );
// ...
However, that broke some existing code (which I've since fixed on the branch) that relied upon the implicit conversion. Despite the breakage, I think making the constructors explicit is a Good Thing because it highlights places in the code where you're actually constructing an expensive-to-construct (by comparison to a built-in arithmetic type) class object by "accident" by now forcing to you explicitly construct them.
For example, the Collection class has member functions that take "integers" like addNode(), nodeAt(), removeNodes(), etc., as xs_integer rather than something like int. In some cases, the arguments were cast to uint64_t despite the reality that the arguments were implicitly being converted to xs_integer. It's not clear why the uint64_t cast was there.
I've changed the owner of the branch to zorba-coders so you can make any necessary changes. In particular, look at the changes in files that are NOT in the zorbatypes sub-directory.
--
https://code.launchpad.net/~zorba-coders/zorba/bug-966355/+merge/102128
Your team Zorba Coders is subscribed to branch lp:zorba.
=== modified file 'src/annotations/annotations.h'
--- src/annotations/annotations.h 2012-03-30 19:03:09 +0000
+++ src/annotations/annotations.h 2012-04-16 15:38:09 +0000
@@ -83,7 +83,7 @@
};
protected:
- typedef std::bitset<zann_end + 1> RuleBitSet;
+ typedef std::bitset<static_cast<int>(zann_end) + 1> RuleBitSet;
protected:
static std::vector<store::Item_t> theAnnotId2NameMap;
=== modified file 'src/compiler/rewriter/rules/flwor_rules.cpp'
--- src/compiler/rewriter/rules/flwor_rules.cpp 2012-04-05 18:06:01 +0000
+++ src/compiler/rewriter/rules/flwor_rules.cpp 2012-04-16 15:38:09 +0000
@@ -1037,7 +1037,7 @@
err::XPTY0004);
if (TypeOps::is_subtype(tm, *valType, *rtm.INTEGER_TYPE_ONE, posLoc) &&
- val->getIntegerValue() >= xs_integer::one())
+ val->getIntegerValue() >= 1)
{
return true;
}
=== modified file 'src/compiler/rewriter/rules/fold_rules.cpp'
--- src/compiler/rewriter/rules/fold_rules.cpp 2012-03-30 19:03:09 +0000
+++ src/compiler/rewriter/rules/fold_rules.cpp 2012-04-16 15:38:09 +0000
@@ -928,19 +928,19 @@
{
xs_integer ival = val->getIntegerValue();
- if (ival < xs_integer::zero())
+ if (ival < 0)
{
if (!count_expr->isNonDiscardable())
return new const_expr(val_expr->get_sctx(), LOC(val_expr), false);
}
- else if (ival == xs_integer::zero())
+ else if (ival == 0)
{
return expr_tools::fix_annotations(
new fo_expr(fo.get_sctx(), fo.get_loc(),
GET_BUILTIN_FUNCTION(FN_EMPTY_1),
count_expr->get_arg(0)));
}
- else if (ival == xs_integer::one())
+ else if (ival == 1)
{
return expr_tools::fix_annotations(
new fo_expr(fo.get_sctx(),
=== modified file 'src/compiler/translator/translator.cpp'
--- src/compiler/translator/translator.cpp 2012-04-12 02:08:10 +0000
+++ src/compiler/translator/translator.cpp 2012-04-16 15:38:09 +0000
@@ -9754,8 +9754,8 @@
{
case FunctionConsts::FN_HEAD_1:
{
- arguments.push_back(new const_expr(theRootSctx, loc, xs_integer(1)));
- arguments.push_back(new const_expr(theRootSctx, loc, xs_integer(1)));
+ arguments.push_back(new const_expr(theRootSctx, loc, xs_integer::one()));
+ arguments.push_back(new const_expr(theRootSctx, loc, xs_integer::one()));
function* f = GET_BUILTIN_FUNCTION(OP_ZORBA_SUBSEQUENCE_INT_3);
fo_expr_t foExpr = new fo_expr(theRootSctx, loc, f, arguments);
normalize_fo(foExpr);
=== modified file 'src/runtime/collections/collections_impl.cpp'
--- src/runtime/collections/collections_impl.cpp 2012-04-14 06:12:29 +0000
+++ src/runtime/collections/collections_impl.cpp 2012-04-16 15:38:09 +0000
@@ -451,7 +451,7 @@
{
store::Collection_t collection;
store::Item_t node;
- xs_integer pos = 1;
+ xs_integer pos( 1 );
bool found;
PlanIteratorState* state;
@@ -466,8 +466,7 @@
found = collection->findNode(node, pos);
ZORBA_ASSERT(found);
- STACK_PUSH(GENV_ITEMFACTORY->createInteger(result, pos+xs_integer(1)),
- state);
+ STACK_PUSH(GENV_ITEMFACTORY->createInteger(result, pos+1), state);
}
STACK_END (state);
@@ -1638,7 +1637,7 @@
const StaticallyKnownCollection* collectionDecl;
store::Item_t collectionName;
store::Item_t numNodesItem;
- xs_integer numNodes = 1;
+ xs_integer numNodes( 1 );
std::vector<store::Item_t> nodes;
std::auto_ptr<store::PUL> pul;
@@ -1674,7 +1673,7 @@
// create the pul and add the primitive
pul.reset(GENV_ITEMFACTORY->createPendingUpdateList());
- for (xs_integer i = 0; i < numNodes; ++i)
+ for (xs_integer i( 0 ); i < numNodes; ++i)
nodes.push_back(collection->nodeAt(i));
pul->addDeleteFromCollection(&loc, collectionName, nodes, false, theDynamicCollection);
@@ -1762,7 +1761,7 @@
const StaticallyKnownCollection* collectionDecl;
store::Item_t collectionName;
store::Item_t numNodesItem;
- xs_integer numNodes = 1;
+ xs_integer numNodes( 1 );
std::vector<store::Item_t> nodes;
std::auto_ptr<store::PUL> pul;
@@ -1796,7 +1795,7 @@
// create the pul and add the primitive
pul.reset(GENV_ITEMFACTORY->createPendingUpdateList());
- for (xs_integer i = numNodes; i > xs_integer(0); --i)
+ for (xs_integer i = numNodes; i > 0; --i)
nodes.push_back(collection->nodeAt(collection->size() - i));
pul->addDeleteFromCollection(&loc, collectionName, nodes, true, theDynamicCollection);
=== modified file 'src/runtime/core/gflwor/window_iterator.cpp'
--- src/runtime/core/gflwor/window_iterator.cpp 2012-04-09 23:08:06 +0000
+++ src/runtime/core/gflwor/window_iterator.cpp 2012-04-16 15:38:09 +0000
@@ -150,7 +150,7 @@
if (!theCurVars.empty())
{
- aInputSeq->getItem(aPosition, lItem);
+ aInputSeq->getItem(xs_integer(aPosition), lItem);
bindVariables(lItem, theCurVars, aPlanState);
}
@@ -158,7 +158,7 @@
{
if (aPosition > 1)
{
- aInputSeq->getItem(aPosition - 1, lItem);
+ aInputSeq->getItem(xs_integer(aPosition - 1), lItem);
}
else
{
@@ -170,9 +170,9 @@
if (!theNextVars.empty())
{
- if (aInputSeq->containsItem(aPosition + 1))
+ if (aInputSeq->containsItem(xs_integer(aPosition + 1)))
{
- aInputSeq->getItem(aPosition + 1, lItem);
+ aInputSeq->getItem(xs_integer(aPosition + 1), lItem);
}
else
{
@@ -185,7 +185,7 @@
if (!thePosVars.empty())
{
store::Item_t lPosItem;
- GENV_ITEMFACTORY->createInteger(lPosItem, Integer(aPosition));
+ GENV_ITEMFACTORY->createInteger(lPosItem, xs_integer(aPosition));
bindVariables(lPosItem, thePosVars, aPlanState);
}
}
@@ -208,7 +208,7 @@
if (!theCurOuterVars.empty())
{
- aInputSeq->getItem(aPosition, lItem);
+ aInputSeq->getItem(xs_integer(aPosition), lItem);
bindVariables(lItem, theCurOuterVars, aPlanState);
}
@@ -216,7 +216,7 @@
{
if (aPosition > 1)
{
- aInputSeq->getItem(aPosition - 1, lItem);
+ aInputSeq->getItem(xs_integer(aPosition - 1), lItem);
}
else
{
@@ -228,9 +228,9 @@
if (!theNextOuterVars.empty())
{
- if (aInputSeq->containsItem(aPosition + 1))
+ if (aInputSeq->containsItem(xs_integer(aPosition + 1)))
{
- aInputSeq->getItem(aPosition + 1, lItem);
+ aInputSeq->getItem(xs_integer(aPosition + 1), lItem);
}
else
{
@@ -716,11 +716,14 @@
ulong aStartPos,
ulong aEndPos) const
{
+ xs_integer const lStartPos( aStartPos );
+ xs_integer const lEndPos( aEndPos );
+
for (std::vector<LetVarIter_t>::const_iterator lVarIter = theVarRefs.begin();
lVarIter != theVarRefs.end();
++lVarIter)
{
- (*lVarIter)->bind(aInputSeq, aPlanState, aStartPos, aEndPos);
+ (*lVarIter)->bind(aInputSeq, aPlanState, lStartPos, lEndPos);
}
}
@@ -736,13 +739,13 @@
if (lState->theOpenWindows.empty())
{
if (lState->theCurInputPos > theMaxNeededHistory)
- lState->theDomainSeq->purgeUpTo(lState->theCurInputPos - theMaxNeededHistory);
+ lState->theDomainSeq->purgeUpTo(xs_integer(lState->theCurInputPos - theMaxNeededHistory));
}
else
{
int32_t lPurgeTo = lState->theOpenWindows.front().theStartPos - theMaxNeededHistory;
if (lPurgeTo > 0)
- lState->theDomainSeq->purgeUpTo(lPurgeTo);
+ lState->theDomainSeq->purgeUpTo(xs_integer(lPurgeTo));
}
}
}
@@ -769,7 +772,8 @@
if (theWindowType == WindowIterator::SLIDING)
{
// Get the next item from the domain sequence
- while (lState->theDomainSeq->containsItem(lState->theCurInputPos))
+ // TODO: can the xs_integer be hoisted?
+ while (lState->theDomainSeq->containsItem(xs_integer(lState->theCurInputPos)))
{
// If the current item satisfies the start condition, create a candidate
// window starting at the current domain item.
@@ -857,7 +861,8 @@
// Doing this switch now also avoids further overhad
if (theEndClause.theHasEndClause)
{
- while (lState->theDomainSeq->containsItem(lState->theCurInputPos))
+ // TODO: can the xs_integer be hoisted?
+ while (lState->theDomainSeq->containsItem(xs_integer(lState->theCurInputPos)))
{
if (lState->theOpenWindows.empty() &&
theStartClause.evaluate(aPlanState,
@@ -898,7 +903,8 @@
}
else
{
- while (lState->theDomainSeq->containsItem(lState->theCurInputPos))
+ // TODO: can the xs_integer be hoisted?
+ while (lState->theDomainSeq->containsItem(xs_integer(lState->theCurInputPos)))
{
if (theStartClause.evaluate(aPlanState,
lState->theDomainSeq,
=== modified file 'src/runtime/core/trycatch.cpp'
--- src/runtime/core/trycatch.cpp 2012-04-09 23:08:06 +0000
+++ src/runtime/core/trycatch.cpp 2012-04-16 15:38:09 +0000
@@ -274,7 +274,8 @@
// function arity
lTypeName = GENV_TYPESYSTEM.XS_UNTYPED_QNAME;
- GENV_ITEMFACTORY->createInteger( lTmpValue, lIter->getFnArity() );
+ GENV_ITEMFACTORY->createInteger(
+ lTmpValue, xs_integer(lIter->getFnArity()));
GENV_ITEMFACTORY->createAttributeNode(
lTmpAttr, lFunction.getp(), lArityQName, lTypeName,
lTmpValue);
@@ -289,28 +290,31 @@
// location line begin
lTypeName = GENV_TYPESYSTEM.XS_UNTYPED_QNAME;
- GENV_ITEMFACTORY->createInteger( lTmpValue, lIter->getLine() );
+ GENV_ITEMFACTORY->createInteger( lTmpValue, xs_integer(lIter->getLine()) );
GENV_ITEMFACTORY->createAttributeNode(
lTmpAttr, lLocation.getp(), lLineBeginQName, lTypeName,
lTmpValue);
// location line end
lTypeName = GENV_TYPESYSTEM.XS_UNTYPED_QNAME;
- GENV_ITEMFACTORY->createInteger( lTmpValue, lIter->getLineEnd() );
+ GENV_ITEMFACTORY->createInteger(
+ lTmpValue, xs_integer(lIter->getLineEnd()));
GENV_ITEMFACTORY->createAttributeNode(
lTmpAttr, lLocation.getp(), lLineEndQName, lTypeName,
lTmpValue);
// location column begin
lTypeName = GENV_TYPESYSTEM.XS_UNTYPED_QNAME;
- GENV_ITEMFACTORY->createInteger( lTmpValue, lIter->getColumn() );
+ GENV_ITEMFACTORY->createInteger(
+ lTmpValue, xs_integer(lIter->getColumn()));
GENV_ITEMFACTORY->createAttributeNode(
lTmpAttr, lLocation.getp(), lColumnBeginQName, lTypeName,
lTmpValue);
// location column end
lTypeName = GENV_TYPESYSTEM.XS_UNTYPED_QNAME;
- GENV_ITEMFACTORY->createInteger( lTmpValue, lIter->getColumnEnd() );
+ GENV_ITEMFACTORY->createInteger(
+ lTmpValue, xs_integer(lIter->getColumnEnd()));
GENV_ITEMFACTORY->createAttributeNode(
lTmpAttr, lLocation.getp(), lColumnEndQName, lTypeName,
lTmpValue);
@@ -446,7 +450,8 @@
if ( ( ue = dynamic_cast<XQueryException const*>( &e ) ) &&
ue->has_source() ) {
store::Item_t lErrorLineItem;
- GENV_ITEMFACTORY->createInteger(lErrorLineItem, ue->source_line());
+ GENV_ITEMFACTORY->createInteger(
+ lErrorLineItem, xs_integer(ue->source_line()));
lErrorLineIter = new ItemIterator(lErrorLineItem);
}
else
@@ -472,7 +477,8 @@
if ( ( ue = dynamic_cast<XQueryException const*>( &e ) ) &&
ue->has_source() ) {
store::Item_t lErrorColumnItem;
- GENV_ITEMFACTORY->createInteger(lErrorColumnItem, ue->source_column());
+ GENV_ITEMFACTORY->createInteger(
+ lErrorColumnItem, xs_integer(ue->source_column()));
lErrorColumnIter = new ItemIterator(lErrorColumnItem);
}
else
=== modified file 'src/runtime/maths/maths_impl.cpp'
--- src/runtime/maths/maths_impl.cpp 2012-03-30 19:03:09 +0000
+++ src/runtime/maths/maths_impl.cpp 2012-04-16 15:38:09 +0000
@@ -500,7 +500,7 @@
PlanIteratorState* state;
DEFAULT_STACK_INIT ( PlanIteratorState, state, planState );
- GENV_ITEMFACTORY->createDouble(result, 3.141592653589793e0);
+ GENV_ITEMFACTORY->createDouble(result, xs_double(3.141592653589793e0));
STACK_PUSH (true, state);
STACK_END (state);
=== modified file 'src/runtime/numerics/format_integer_impl.cpp'
--- src/runtime/numerics/format_integer_impl.cpp 2012-03-30 19:03:09 +0000
+++ src/runtime/numerics/format_integer_impl.cpp 2012-04-16 15:38:09 +0000
@@ -164,8 +164,8 @@
static const unsigned int letter_range = 'Z' - 'A' + 1;
static xs_integer integer_digit(letter_range);
xs_integer upper_int = valueInteger/integer_digit;
- if(upper_int > xs_integer::zero())
- formatIntegerAZ(upper_int - xs_integer::one(), c0, resultString);
+ if(upper_int > 0)
+ formatIntegerAZ(upper_int - 1, c0, resultString);
xs_integer mod_integer = valueInteger % integer_digit;
xs_int mod_int = to_xs_int(mod_integer);
resultString += (c0 + mod_int);
@@ -426,7 +426,7 @@
formatIntegerEnglish(valueInteger/integer_##big_number_name, false, resultString); \
resultString += " " #big_number_name; \
value_mod = valueInteger % integer_##big_number_name; \
- if(value_mod > xs_integer::zero()) \
+ if(value_mod > 0) \
{ \
resultString += " "; \
formatIntegerEnglish(value_mod, is_ordinal, resultString); \
@@ -439,7 +439,7 @@
else if (valueInteger >= integer_##decim) \
{ \
value_mod = valueInteger % integer_##decim; \
- if(value_mod > xs_integer::zero()) \
+ if(value_mod > 0) \
{ \
resultString += decim_cardinal; \
resultString += "-"; \
@@ -504,7 +504,7 @@
IF_GE_DECIM(3, "three", "third")
IF_GE_DECIM(2, "two", "second")
IF_GE_DECIM(1, "one", "first")
- else if (valueInteger == xs_integer::zero())
+ else if (valueInteger == 0)
{
if(!is_ordinal)
resultString += "zero";
@@ -771,7 +771,7 @@
if (consumeNext(value_item, theChildren[0].getp(), planState))
{
valueInteger = value_item->getIntegerValue();
- if(valueInteger < xs_integer::zero())
+ if(valueInteger < 0)
{
valueInteger = -valueInteger;
is_neg = true;
@@ -811,17 +811,17 @@
if((c0 == 'a') || (c0 == 'A'))
{
checkOptionalModifier(utf8_picture, 1, &is_ordinal, &is_traditional, utf8_word_terminal);
- if(valueInteger > xs_integer::zero())
+ if(valueInteger > 0)
{
if(is_neg)
resultString += '-';
- formatIntegerAZ(valueInteger-xs_integer::one(), c0, resultString);
+ formatIntegerAZ(valueInteger-1, c0, resultString);
}
}
else if((c0 == 'i') || (c0 == 'I'))
{
checkOptionalModifier(utf8_picture, 1, &is_ordinal, &is_traditional, utf8_word_terminal);
- if(valueInteger > xs_integer::zero())
+ if(valueInteger > 0)
{
if(is_neg)
resultString += ("-");
=== modified file 'src/runtime/random/random_impl.cpp'
--- src/runtime/random/random_impl.cpp 2012-03-30 19:03:09 +0000
+++ src/runtime/random/random_impl.cpp 2012-04-16 15:38:09 +0000
@@ -45,7 +45,7 @@
consumeNext(seed, theChildren[0].getp(), planState);
consumeNext(num, theChildren[1].getp(), planState);
- if ( num->getIntegerValue() < xs_integer( 0 ) )
+ if ( num->getIntegerValue() < 0 )
{
STACK_PUSH(false, state);
}
@@ -110,7 +110,7 @@
DEFAULT_STACK_INIT(RandomIteratorState, state, planState);
consumeNext(num, theChildren[0].getp(), planState);
- if ( num->getIntegerValue() < xs_integer( 0 ) )
+ if ( num->getIntegerValue() < 0 )
{
STACK_PUSH(false, state);
}
=== modified file 'src/runtime/sequences/sequences_impl.cpp'
--- src/runtime/sequences/sequences_impl.cpp 2012-03-30 19:03:09 +0000
+++ src/runtime/sequences/sequences_impl.cpp 2012-04-16 15:38:09 +0000
@@ -322,12 +322,12 @@
}
state->thePosition = lPositionItem->getIntegerValue();
- if (state->thePosition < xs_integer::one())
- state->thePosition = xs_integer::one();
+ if (state->thePosition < 1)
+ state->thePosition = 1;
while (consumeNext(result, theChildren[0].getp(), planState))
{
- if ( state->theCurrentPos == state->thePosition-xs_integer::one() ) // position found => insert sequence
+ if ( state->theCurrentPos == state->thePosition-1 ) // position found => insert sequence
{
state->theTargetItem = result;
while ( consumeNext(result, theChildren[2].getp(), planState))
=== modified file 'src/runtime/store/maps_impl.cpp'
--- src/runtime/store/maps_impl.cpp 2012-03-30 19:03:09 +0000
+++ src/runtime/store/maps_impl.cpp 2012-04-16 15:38:09 +0000
@@ -540,7 +540,7 @@
);
}
- GENV_ITEMFACTORY->createInteger(result, lIndex->size());
+ GENV_ITEMFACTORY->createInteger(result, xs_integer(lIndex->size()));
STACK_PUSH(true, state);
=== modified file 'src/store/naive/atomic_items.cpp'
--- src/store/naive/atomic_items.cpp 2012-03-30 19:03:09 +0000
+++ src/store/naive/atomic_items.cpp 2012-04-16 15:38:09 +0000
@@ -1472,7 +1472,7 @@
store::Item_t StructuralAnyUriItem::getLevel() const
{
store::Item_t lResult;
- GET_FACTORY().createInteger(lResult, theOrdPath.getLevel());
+ GET_FACTORY().createInteger(lResult, xs_integer(theOrdPath.getLevel()));
return lResult;
}
@@ -2747,7 +2747,7 @@
}
xs_nonNegativeInteger LongItem::getUnsignedIntegerValue() const {
- return theValue >= 0 ? theValue : -theValue;
+ return xs_nonNegativeInteger( theValue >= 0 ? theValue : -theValue );
}
store::Item* LongItem::getType() const
=== modified file 'src/store/naive/collection.h'
--- src/store/naive/collection.h 2012-03-28 23:58:23 +0000
+++ src/store/naive/collection.h 2012-04-16 15:38:09 +0000
@@ -65,7 +65,7 @@
/************************* Updates on collection ****************************/
- virtual void addNode(store::Item* node, xs_integer position = -1) = 0;
+ virtual void addNode(store::Item* node, xs_integer position = xs_integer(-1)) = 0;
virtual zorba::xs_integer addNodes(
std::vector<store::Item_t>& nodes,
=== modified file 'src/store/naive/node_items.cpp'
--- src/store/naive/node_items.cpp 2012-04-12 02:08:10 +0000
+++ src/store/naive/node_items.cpp 2012-04-16 15:38:09 +0000
@@ -1294,7 +1294,7 @@
lCurrent = lCurrent->getParent();
}
store::Item_t lRes;
- GET_FACTORY().createInteger(lRes, lNumLevels);
+ GET_FACTORY().createInteger(lRes, xs_integer(lNumLevels));
return lRes;
}
=== modified file 'src/store/naive/pul_primitives.cpp'
--- src/store/naive/pul_primitives.cpp 2012-03-30 19:03:09 +0000
+++ src/store/naive/pul_primitives.cpp 2012-04-16 15:38:09 +0000
@@ -986,7 +986,7 @@
for (uint64_t i = 0; i < size; ++i)
{
- XmlNode* root = static_cast<XmlNode*>(collection->nodeAt(i).getp());
+ XmlNode* root = static_cast<XmlNode*>(collection->nodeAt(xs_integer(i)).getp());
XmlTree* tree = root->getTree();
if (tree->getRefCount() > 1)
throw XQUERY_EXCEPTION(
@@ -1021,7 +1021,7 @@
std::size_t numNodes = theNodes.size();
for (std::size_t i = 0; i < numNodes; ++i)
{
- lColl->addNode(theNodes[i], -1);
+ lColl->addNode(theNodes[i], xs_integer(-1));
++theNumApplied;
}
}
@@ -1051,9 +1051,10 @@
for (long i = theNumApplied-1; i >= 0; --i)
{
- ZORBA_ASSERT(theNodes[i] == lColl->nodeAt(lastPos));
+ xs_integer xs_lastPos( lastPos );
+ ZORBA_ASSERT(theNodes[i] == lColl->nodeAt(xs_lastPos));
- lColl->removeNode(lastPos);
+ lColl->removeNode(xs_lastPos);
--lastPos;
}
}
@@ -1075,7 +1076,7 @@
std::size_t numNodes = theNodes.size();
for (std::size_t i = 0; i < numNodes; ++i)
{
- lColl->addNode(theNodes[i], i);
+ lColl->addNode(theNodes[i], xs_integer(i));
++theNumApplied;
}
}
@@ -1087,11 +1088,12 @@
(GET_STORE().getCollection(theName, theDynamicCollection).getp());
assert(lColl);
+ xs_integer const zero( xs_integer::zero() );
for (std::size_t i = 0; i < theNumApplied; ++i)
{
- ZORBA_ASSERT(theNodes[i] == lColl->nodeAt(0));
+ ZORBA_ASSERT(theNodes[i] == lColl->nodeAt(zero));
- lColl->removeNode((uint64_t)0);
+ lColl->removeNode(zero);
}
}
@@ -1108,9 +1110,10 @@
theIsApplied = true;
std::size_t numNodes = theNodes.size();
+ xs_integer const neg_1( -1 );
for (std::size_t i = 0; i < numNodes; ++i)
{
- lColl->addNode(theNodes[i], -1);
+ lColl->addNode(theNodes[i], neg_1);
}
}
@@ -1135,11 +1138,12 @@
);
}
+ xs_integer const xs_lastPos( lastPos );
for (long i = theNumApplied-1; i >= 0; --i)
{
- ZORBA_ASSERT(theNodes[i] == lColl->nodeAt(lastPos));
+ ZORBA_ASSERT(theNodes[i] == lColl->nodeAt(xs_lastPos));
- lColl->removeNode(lastPos);
+ lColl->removeNode(xs_lastPos);
}
}
@@ -1170,7 +1174,7 @@
assert(lColl);
ZORBA_ASSERT(theFirstNode == lColl->nodeAt(theFirstPos));
- lColl->removeNodes(theFirstPos, (uint64_t)theNodes.size());
+ lColl->removeNodes(theFirstPos, xs_integer(theNodes.size()));
}
@@ -1201,7 +1205,7 @@
assert(lColl);
ZORBA_ASSERT(theFirstNode == lColl->nodeAt(theFirstPos));
- lColl->removeNodes(theFirstPos, (uint64_t)theNodes.size());
+ lColl->removeNodes(theFirstPos, xs_integer(theNodes.size()));
}
@@ -1240,7 +1244,7 @@
{
for (std::size_t i = numNodes; i > 0; --i)
{
- if (theNodes[i-1] != lColl->nodeAt(size - i))
+ if (theNodes[i-1] != lColl->nodeAt(xs_integer(size - i)))
{
isLast = false;
break;
=== modified file 'src/store/naive/simple_collection.cpp'
--- src/store/naive/simple_collection.cpp 2012-03-30 19:03:09 +0000
+++ src/store/naive/simple_collection.cpp 2012-04-16 15:38:09 +0000
@@ -124,16 +124,16 @@
SYNC_CODE(AutoLatch lock(theLatch, Latch::WRITE););
- if (lPosition < 0 || to_xs_unsignedLong(lPosition) >= theXmlTrees.size())
+ if (lPosition < 0 || lPosition >= theXmlTrees.size())
{
theXmlTrees.push_back(nodeItem);
- node->setCollection(this, (uint64_t)theXmlTrees.size() - 1);
+ node->setCollection(this, xs_integer(theXmlTrees.size() - 1));
}
else
{
theXmlTrees.insert(theXmlTrees.begin() + (std::size_t)lPosition, nodeItem);
- node->setCollection(this, to_xs_unsignedInt(lPosition));
+ node->setCollection(this, xs_integer(lPosition));
}
}
@@ -203,7 +203,7 @@
);
}
- node->setCollection(this, lTargetPos + i);
+ node->setCollection(this, xs_integer(lTargetPos + i));
}
theXmlTrees.resize(numNodes + numNewNodes);
@@ -232,7 +232,7 @@
theXmlTrees[lTargetPos + i].transfer(nodes[i]);
}
- return lTargetPos;
+ return xs_integer( lTargetPos );
}
@@ -261,7 +261,7 @@
{
ZORBA_ASSERT(node->getCollection() == this);
- node->setCollection(NULL, 0);
+ node->setCollection(NULL, xs_integer(0));
std::size_t lPosition = to_xs_unsignedInt(position);
theXmlTrees.erase(theXmlTrees.begin() + lPosition);
return true;
@@ -292,7 +292,7 @@
XmlNode* node = static_cast<XmlNode*>(theXmlTrees[lPosition].getp());
ZORBA_ASSERT(node->getCollection() == this);
- node->setCollection(NULL, 0);
+ node->setCollection(NULL, xs_integer(0));
theXmlTrees.erase(theXmlTrees.begin() + lPosition);
return true;
}
@@ -314,7 +314,7 @@
if (lNum == 0 || lPosition >= theXmlTrees.size())
{
- return 0;
+ return xs_integer(0);
}
else
{
@@ -328,12 +328,12 @@
{
XmlNode* node = static_cast<XmlNode*>(theXmlTrees[lPosition].getp());
ZORBA_ASSERT(node->getCollection() == this);
- node->setCollection(NULL, 0);
+ node->setCollection(NULL, xs_integer(0));
theXmlTrees.erase(theXmlTrees.begin() + lPosition);
}
- return last-lPosition;
+ return xs_integer(last-lPosition);
}
}
@@ -434,7 +434,7 @@
for (std::size_t i = 0; i < numTrees; ++i)
{
- BASE_NODE(theXmlTrees[i])->getTree()->setPosition(i);
+ BASE_NODE(theXmlTrees[i])->getTree()->setPosition(xs_integer(i));
}
}
=== modified file 'src/store/naive/simple_collection.h'
--- src/store/naive/simple_collection.h 2012-03-30 19:03:09 +0000
+++ src/store/naive/simple_collection.h 2012-04-16 15:38:09 +0000
@@ -100,7 +100,7 @@
const store::Item* getName() const { return theName.getp(); }
- xs_integer size() const { return theXmlTrees.size(); }
+ xs_integer size() const { return xs_integer( theXmlTrees.size() ); }
bool isDynamic() const { return theIsDynamic; }
@@ -110,7 +110,7 @@
store::Iterator_t getIterator();
- void addNode(store::Item* node, xs_integer position = -1);
+ void addNode(store::Item* node, xs_integer position = xs_integer(-1));
xs_integer addNodes(
std::vector<store::Item_t>& nodes,
=== modified file 'src/store/naive/simple_index_general.cpp'
--- src/store/naive/simple_index_general.cpp 2012-03-30 19:03:09 +0000
+++ src/store/naive/simple_index_general.cpp 2012-04-16 15:38:09 +0000
@@ -1667,13 +1667,13 @@
{
if (haveLower)
{
- xs_double doubleValue = lowerKey->getDecimalValue();
+ xs_double const doubleValue( lowerKey->getDecimalValue() );
GET_FACTORY().createDouble(lowerAltKey, doubleValue);
}
if (haveUpper)
{
- xs_double doubleValue = upperKey->getDecimalValue();
+ xs_double const doubleValue( upperKey->getDecimalValue() );
GET_FACTORY().createDouble(upperAltKey, doubleValue);
}
@@ -1697,13 +1697,13 @@
{
if (haveLower)
{
- xs_decimal decimalValue = lowerKey->getLongValue();
+ xs_decimal const decimalValue( lowerKey->getLongValue() );
GET_FACTORY().createDecimal(lowerAltKey, decimalValue);
}
if (haveUpper)
{
- xs_decimal decimalValue = upperKey->getLongValue();
+ xs_decimal const decimalValue( upperKey->getLongValue() );
GET_FACTORY().createDecimal(upperAltKey, decimalValue);
}
@@ -1714,13 +1714,13 @@
{
if (haveLower)
{
- xs_double doubleValue = lowerKey->getLongValue();
+ xs_double doubleValue( lowerKey->getLongValue() );
GET_FACTORY().createDouble(lowerAltKey, doubleValue);
}
if (haveUpper)
{
- xs_double doubleValue = upperKey->getLongValue();
+ xs_double const doubleValue( upperKey->getLongValue() );
GET_FACTORY().createDouble(upperAltKey, doubleValue);
}
@@ -1772,14 +1772,14 @@
if (idx->theMaps[store::XS_DOUBLE])
{
- xs_double doubleValue = longItem->getLongValue();
+ xs_double const doubleValue( longItem->getLongValue() );
GET_FACTORY().createDouble(altKey, doubleValue);
probeMap(store::XS_DOUBLE, altKey, altKey);
}
if (idx->theMaps[store::XS_DECIMAL])
{
- xs_decimal decimalValue = longItem->getLongValue();
+ xs_decimal const decimalValue( longItem->getLongValue() );
GET_FACTORY().createDecimal(altKey, decimalValue);
probeMap(store::XS_DECIMAL, altKey, altKey);
}
@@ -1806,7 +1806,7 @@
if (idx->theMaps[store::XS_DOUBLE])
{
- xs_double doubleValue = decimalItem->getDecimalValue();
+ xs_double const doubleValue( decimalItem->getDecimalValue() );
GET_FACTORY().createDouble(altKey, doubleValue);
probeMap(store::XS_DOUBLE, altKey, altKey);
}
=== modified file 'src/store/naive/simple_lazy_temp_seq.cpp'
--- src/store/naive/simple_lazy_temp_seq.cpp 2012-03-30 19:03:09 +0000
+++ src/store/naive/simple_lazy_temp_seq.cpp 2012-04-16 15:38:09 +0000
@@ -238,7 +238,7 @@
xs_integer SimpleLazyTempSeq::getSize() const
{
ZORBA_ASSERT(false);
- return 0;
+ return xs_integer(0);
}
@@ -250,7 +250,7 @@
********************************************************************************/
store::Iterator_t SimpleLazyTempSeq::getIterator() const
{
- return new SimpleLazyTempSeqIter(this, 1, std::numeric_limits<long>::max());
+ return new SimpleLazyTempSeqIter(this, xs_integer(1), xs_integer(std::numeric_limits<long>::max()));
}
@@ -307,9 +307,9 @@
bool SimpleLazyTempSeqIter::next(store::Item_t& result)
{
- if (theCurPos < theEndPos && theTempSeq->containsItem(theCurPos+1))
+ if (theCurPos < theEndPos && theTempSeq->containsItem(xs_integer(theCurPos+1)))
{
- theTempSeq->getItem(++theCurPos, result);
+ theTempSeq->getItem(xs_integer(++theCurPos), result);
return true;
}
else
=== modified file 'src/store/naive/simple_temp_seq.cpp'
--- src/store/naive/simple_temp_seq.cpp 2012-03-30 19:03:09 +0000
+++ src/store/naive/simple_temp_seq.cpp 2012-04-16 15:38:09 +0000
@@ -133,7 +133,7 @@
********************************************************************************/
xs_integer SimpleTempSeq::getSize() const
{
- return theItems.size();
+ return xs_integer( theItems.size() );
}
=== modified file 'src/zorbatypes/decimal.cpp'
--- src/zorbatypes/decimal.cpp 2012-04-12 02:08:10 +0000
+++ src/zorbatypes/decimal.cpp 2012-04-16 15:38:09 +0000
@@ -334,15 +334,15 @@
TEMPLATE_DECL(T)
Decimal Decimal::round( INTEGER_IMPL(T) const &precision ) const {
- return round( value_, precision.itod() );
+ return round2( value_, precision.itod() );
}
#ifndef ZORBA_WITH_BIG_INTEGER
template Decimal Decimal::round( INTEGER_IMPL_LL const& ) const;
template Decimal Decimal::round( INTEGER_IMPL_ULL const& ) const;
#endif /* ZORBA_WITH_BIG_INTEGER */
-Decimal::value_type Decimal::round( value_type const &v,
- value_type const &precision ) {
+Decimal::value_type Decimal::round2( value_type const &v,
+ value_type const &precision ) {
value_type const exp( value_type(10).pow( precision ) );
value_type result( v * exp );
result += MAPM::get0_5();
@@ -353,22 +353,22 @@
TEMPLATE_DECL(T)
Decimal Decimal::roundHalfToEven( INTEGER_IMPL(T) const &precision ) const {
- return roundHalfToEven( value_, precision.itod() );
+ return roundHalfToEven2( value_, precision.itod() );
}
#ifndef ZORBA_WITH_BIG_INTEGER
template Decimal Decimal::roundHalfToEven( INTEGER_IMPL_LL const& ) const;
template Decimal Decimal::roundHalfToEven( INTEGER_IMPL_ULL const& ) const;
#endif /* ZORBA_WITH_BIG_INTEGER */
-Decimal::value_type Decimal::roundHalfToEven( value_type const &v,
- value_type const &precision ) {
+Decimal::value_type Decimal::roundHalfToEven2( value_type const &v,
+ value_type const &precision ) {
value_type const exp( value_type(10).pow( precision ) );
value_type result( v * exp );
bool const aHalfVal = (result - MAPM::get0_5()) == result.floor();
result += MAPM::get0_5();
result = result.floor();
if ( aHalfVal && result.is_odd() )
- result -= 1;
+ --result;
result /= exp;
return result;
}
=== modified file 'src/zorbatypes/decimal.h'
--- src/zorbatypes/decimal.h 2012-03-30 19:03:09 +0000
+++ src/zorbatypes/decimal.h 2012-04-16 15:38:09 +0000
@@ -21,6 +21,7 @@
#include <zorba/config.h>
#include "common/common.h"
+#include "util/stl_util.h"
#include "zorbaserialization/archiver.h"
#include "zorbaserialization/class_serializer.h"
@@ -30,11 +31,11 @@
#include "zstring.h"
#ifdef ZORBA_WITH_BIG_INTEGER
-# define TEMPLATE_DECL(T) /* nothing */
-# define INTEGER_IMPL(T) IntegerImpl
+# define TEMPLATE_DECL(I) /* nothing */
+# define INTEGER_IMPL(I) IntegerImpl
#else
-# define TEMPLATE_DECL(T) template<typename T>
-# define INTEGER_IMPL(T) IntegerImpl<T>
+# define TEMPLATE_DECL(I) template<typename I>
+# define INTEGER_IMPL(I) IntegerImpl<I>
#endif /* ZORBA_WITH_BIG_INTEGER */
namespace zorba {
@@ -46,23 +47,22 @@
////////// constructors /////////////////////////////////////////////////////
- Decimal( char c );
- Decimal( signed char c );
- Decimal( short n );
- Decimal( int n = 0 );
- Decimal( long n );
- Decimal( long long n );
- Decimal( unsigned char c );
- Decimal( unsigned short n );
- Decimal( unsigned int n );
- Decimal( unsigned long n );
- Decimal( unsigned long long n );
- Decimal( float n );
- Decimal( double n );
- Decimal( Decimal const &d );
+ explicit Decimal( char c );
+ explicit Decimal( signed char c );
+ explicit Decimal( short n );
+ explicit Decimal( int n = 0 );
+ explicit Decimal( long n );
+ explicit Decimal( long long n );
+ explicit Decimal( unsigned char c );
+ explicit Decimal( unsigned short n );
+ explicit Decimal( unsigned int n );
+ explicit Decimal( unsigned long n );
+ explicit Decimal( unsigned long long n );
+ explicit Decimal( float n );
+ explicit Decimal( double n );
- TEMPLATE_DECL(T)
- Decimal( INTEGER_IMPL(T) const &i );
+ TEMPLATE_DECL(I)
+ explicit Decimal( INTEGER_IMPL(I) const &i );
/**
* Constructs a %Decimal from a C string.
@@ -71,7 +71,7 @@
* whitespace is ignored.
* @throw std::invalid_argument if \a s does not contain a valid decimal.
*/
- Decimal( char const *s );
+ explicit Decimal( char const *s );
/**
* Constructs a %Decimal from a Double.
@@ -79,7 +79,7 @@
* @param n The Double.
* @throw std::invalid_argument if \a n is not finite.
*/
- Decimal( Double const &n );
+ explicit Decimal( Double const &n );
/**
* Constructs a %Decimal from a Float.
@@ -87,30 +87,46 @@
* @param n The Float.
* @throw std::invalid_argument if \a n is not finite.
*/
- Decimal( Float const &n );
+ explicit Decimal( Float const &n );
+
+ /**
+ * Conventional copy constructor.
+ *
+ * @param d The %Decimal to copy from.
+ */
+ Decimal( Decimal const &d );
////////// assignment operators /////////////////////////////////////////////
- Decimal& operator=( char c );
- Decimal& operator=( signed char c );
- Decimal& operator=( short n );
- Decimal& operator=( int n );
- Decimal& operator=( long n );
+ /**
+ * Conventional assignment operator.
+ *
+ * @param d The %Decimal to assign from.
+ * @return Returns \c *this.
+ */
+ Decimal& operator=( Decimal const &d );
+
+ /**
+ * For every built-in arithmetic type A, assign to this %Decimal.
+ *
+ * @tparam A The built-in arithmetic type.
+ * @param n The arithmetic value to assign.
+ * @return Returns \c *this.
+ */
+ template<typename A>
+ typename std::enable_if<ZORBA_TR1_NS::is_arithmetic<A>::value,Decimal&>::type
+ operator=( A n );
+
+ // These arithmetic types have to be special-cased.
Decimal& operator=( long long n );
- Decimal& operator=( unsigned char c );
- Decimal& operator=( unsigned short n );
- Decimal& operator=( unsigned int n );
- Decimal& operator=( unsigned long n );
Decimal& operator=( unsigned long long n );
- Decimal& operator=( float n );
- Decimal& operator=( double n );
+
Decimal& operator=( char const *s );
- Decimal& operator=( Decimal const &d );
Decimal& operator=( Double const &d );
Decimal& operator=( Float const &f );
- TEMPLATE_DECL(T)
- Decimal& operator=( INTEGER_IMPL(T) const &i );
+ TEMPLATE_DECL(I)
+ Decimal& operator=( INTEGER_IMPL(I) const &i );
////////// arithmetic operators /////////////////////////////////////////////
@@ -121,10 +137,11 @@
friend Decimal operator%( Decimal const&, Decimal const& );
#define ZORBA_DECIMAL_OP(OP) \
- TEMPLATE_DECL(T) \
- friend Decimal operator OP( Decimal const&, INTEGER_IMPL(T) const& ); \
- TEMPLATE_DECL(T) \
- friend Decimal operator OP( INTEGER_IMPL(T) const&, Decimal const& )
+ TEMPLATE_DECL(I) \
+ friend Decimal operator OP( Decimal const&, INTEGER_IMPL(I) const& ); \
+ \
+ TEMPLATE_DECL(I) \
+ friend Decimal operator OP( INTEGER_IMPL(I) const&, Decimal const& )
ZORBA_DECIMAL_OP(+);
ZORBA_DECIMAL_OP(-);
@@ -140,7 +157,7 @@
Decimal& operator%=( Decimal const& );
#define ZORBA_DECIMAL_OP(OP) \
- TEMPLATE_DECL(T) Decimal& operator OP( INTEGER_IMPL(T) const& )
+ TEMPLATE_DECL(I) Decimal& operator OP( INTEGER_IMPL(I) const& )
ZORBA_DECIMAL_OP(+=);
ZORBA_DECIMAL_OP(-=);
@@ -155,10 +172,10 @@
#define ZORBA_DECIMAL_OP(OP) \
friend bool operator OP( Decimal const&, Decimal const& ); \
- TEMPLATE_DECL(T) \
- friend bool operator OP( Decimal const&, INTEGER_IMPL(T) const& ); \
- TEMPLATE_DECL(T) \
- friend bool operator OP( INTEGER_IMPL(T) const&, Decimal const& )
+ TEMPLATE_DECL(I) \
+ friend bool operator OP( Decimal const&, INTEGER_IMPL(I) const& ); \
+ TEMPLATE_DECL(I) \
+ friend bool operator OP( INTEGER_IMPL(I) const&, Decimal const& )
ZORBA_DECIMAL_OP(==);
ZORBA_DECIMAL_OP(!=);
@@ -176,11 +193,11 @@
Decimal floor() const;
Decimal round() const;
- TEMPLATE_DECL(T)
- Decimal round( INTEGER_IMPL(T) const &precision ) const;
+ TEMPLATE_DECL(I)
+ Decimal round( INTEGER_IMPL(I) const &precision ) const;
- TEMPLATE_DECL(T)
- Decimal roundHalfToEven( INTEGER_IMPL(T) const &precision ) const;
+ TEMPLATE_DECL(I)
+ Decimal roundHalfToEven( INTEGER_IMPL(I) const &precision ) const;
Decimal sqrt() const;
@@ -223,16 +240,16 @@
static void reduce( char *s );
- static value_type round( value_type const &v, value_type const &precision );
+ static value_type round2( value_type const &v, value_type const &precision );
- static value_type roundHalfToEven( value_type const &v,
- value_type const &precision );
+ static value_type roundHalfToEven2( value_type const &v,
+ value_type const &precision );
static zstring toString( value_type const&,
int precision = ZORBA_FLOAT_POINT_PRECISION );
- TEMPLATE_DECL(T) friend class IntegerImpl;
- template<typename T> friend class FloatImpl;
+ TEMPLATE_DECL(I) friend class IntegerImpl;
+ template<typename F> friend class FloatImpl;
friend xs_long to_xs_long( Decimal const& );
};
@@ -274,112 +291,49 @@
////////// assignment operators ///////////////////////////////////////////////
-inline Decimal& Decimal::operator=( char c ) {
- value_ = static_cast<long>( c );
- return *this;
-}
-
-inline Decimal& Decimal::operator=( signed char c ) {
- value_ = static_cast<long>( c );
- return *this;
-}
-
-inline Decimal& Decimal::operator=( short n ) {
- value_ = static_cast<long>( n );
- return *this;
-}
-
-inline Decimal& Decimal::operator=( int n ) {
- value_ = static_cast<long>( n );
- return *this;
-}
-
-inline Decimal& Decimal::operator=( long n ) {
- value_ = n;
- return *this;
-}
-
-inline Decimal& Decimal::operator=( unsigned char c ) {
- value_ = static_cast<long>( c );
- return *this;
-}
-
-inline Decimal& Decimal::operator=( unsigned short n ) {
- value_ = static_cast<long>( n );
- return *this;
-}
-
-inline Decimal& Decimal::operator=( unsigned int n ) {
- value_ = static_cast<long>( n );
- return *this;
-}
-
-inline Decimal& Decimal::operator=( float n ) {
- value_ = n;
- return *this;
-}
-
-inline Decimal& Decimal::operator=( double n ) {
- value_ = n;
- return *this;
-}
-
-inline Decimal& Decimal::operator=( char const *s ) {
- parse( s, &value_ );
- return *this;
-}
-
inline Decimal& Decimal::operator=( Decimal const &d ) {
value_ = d.value_;
return *this;
}
+template<typename A> inline
+typename std::enable_if<ZORBA_TR1_NS::is_arithmetic<A>::value,Decimal&>::type
+Decimal::operator=( A n ) {
+ value_ = static_cast<long>( n );
+ return *this;
+}
+
+inline Decimal& Decimal::operator=( char const *s ) {
+ parse( s, &value_ );
+ return *this;
+}
+
////////// arithmetic operators ///////////////////////////////////////////////
-inline Decimal operator+( Decimal const &d1, Decimal const &d2 ) {
- return d1.value_ + d2.value_;
-}
-
-inline Decimal operator-( Decimal const &d1, Decimal const &d2 ) {
- return d1.value_ - d2.value_;
-}
-
-inline Decimal operator*( Decimal const &d1, Decimal const &d2 ) {
- return d1.value_ * d2.value_;
-}
-
-inline Decimal operator/( Decimal const &d1, Decimal const &d2 ) {
- return d1.value_ / d2.value_;
-}
-
-inline Decimal operator%( Decimal const &d1, Decimal const &d2 ) {
- return d1.value_ % d2.value_;
-}
-
-inline Decimal& Decimal::operator+=( Decimal const &d ) {
- value_ += d.value_;
- return *this;
-}
-
-inline Decimal& Decimal::operator-=( Decimal const &d ) {
- value_ -= d.value_;
- return *this;
-}
-
-inline Decimal& Decimal::operator*=( Decimal const &d ) {
- value_ *= d.value_;
- return *this;
-}
-
-inline Decimal& Decimal::operator/=( Decimal const &d ) {
- value_ /= d.value_;
- return *this;
-}
-
-inline Decimal& Decimal::operator%=( Decimal const &d ) {
- value_ %= d.value_;
- return *this;
-}
+#define ZORBA_DECIMAL_OP(OP) \
+ inline Decimal operator OP( Decimal const &d1, Decimal const &d2 ) { \
+ return d1.value_ OP d2.value_; \
+ }
+
+ZORBA_DECIMAL_OP(+)
+ZORBA_DECIMAL_OP(-)
+ZORBA_DECIMAL_OP(*)
+ZORBA_DECIMAL_OP(/)
+ZORBA_DECIMAL_OP(%)
+#undef ZORBA_DECIMAL_OP
+
+#define ZORBA_DECIMAL_OP(OP) \
+ inline Decimal& Decimal::operator OP( Decimal const &d ) { \
+ value_ OP d.value_; \
+ return *this; \
+ }
+
+ZORBA_DECIMAL_OP(+=)
+ZORBA_DECIMAL_OP(-=)
+ZORBA_DECIMAL_OP(*=)
+ZORBA_DECIMAL_OP(/=)
+ZORBA_DECIMAL_OP(%=)
+#undef ZORBA_DECIMAL_OP
inline Decimal Decimal::operator-() const {
return -value_;
=== modified file 'src/zorbatypes/floatimpl.cpp'
--- src/zorbatypes/floatimpl.cpp 2012-04-12 02:08:10 +0000
+++ src/zorbatypes/floatimpl.cpp 2012-04-16 15:38:09 +0000
@@ -169,22 +169,54 @@
template FloatImpl<double>::FloatImpl( INTEGER_IMPL_ULL const& );
#endif /* ZORBA_WITH_BIG_INTEGER */
+////////// assignment operators ///////////////////////////////////////////////
+
+template<typename FloatType>
+FloatImpl<FloatType>& FloatImpl<FloatType>::operator=( Decimal const &d ) {
+ zstring const temp( d.toString() );
+ parse( temp.c_str() );
+ return *this;
+}
+
+template<typename FloatType>
+TEMPLATE_DECL(IntType)
+FloatImpl<FloatType>&
+FloatImpl<FloatType>::operator=( INTEGER_IMPL(IntType) const &i ) {
+ zstring const temp( i.toString() );
+ parse( temp.c_str() );
+ return *this;
+}
+
+#ifndef ZORBA_WITH_BIG_INTEGER
+template
+FloatImpl<float>& FloatImpl<float>::operator=( INTEGER_IMPL_LL const& );
+
+template
+FloatImpl<float>& FloatImpl<float>::operator=( INTEGER_IMPL_ULL const& );
+
+template
+FloatImpl<double>& FloatImpl<double>::operator=( INTEGER_IMPL_LL const& );
+
+template
+FloatImpl<double>& FloatImpl<double>::operator=( INTEGER_IMPL_ULL const& );
+#endif /* ZORBA_WITH_BIG_INTEGER */
+
////////// math functions /////////////////////////////////////////////////////
template<typename FloatType>
FloatImpl<FloatType> FloatImpl<FloatType>::acos() const {
if ( *this < neg_one() || *this > one() )
return nan();
- if ( !isNegZero() )
- return std::acos( value_ );
- return -std::acos( value_ );
+ return FloatImpl<FloatType>(
+ isNegZero() ? -std::acos( value_ ): std::acos( value_ )
+ );
}
template<typename FloatType>
FloatImpl<FloatType> FloatImpl<FloatType>::asin() const {
if ( *this < neg_one() || *this > one() )
return nan();
- return std::asin( value_ );
+ return FloatImpl<FloatType>( std::asin( value_ ) );
}
template<typename FloatType>
@@ -220,8 +252,13 @@
FloatImpl<FloatType> FloatImpl<FloatType>::round( Integer const &precision ) const {
FloatImpl result;
if ( isFinite() && !isZero() ) {
- MAPM m = Decimal::round( value_, precision.itod() );
- if ( value_ < 0 && m == 0 )
+ MAPM m(
+ Decimal::round2(
+ Decimal::value_type( value_ ),
+ Decimal::value_type( precision.itod() )
+ )
+ );
+ if ( value_ < 0 && m.sign() == 0 )
result = neg_zero();
else {
char buf[200];
@@ -234,12 +271,17 @@
return result;
}
-template<typename FloatType>
-FloatImpl<FloatType> FloatImpl<FloatType>::roundHalfToEven( Integer const &precision) const {
+template<typename FloatType> FloatImpl<FloatType>
+FloatImpl<FloatType>::roundHalfToEven( Integer const &precision) const {
FloatImpl result;
if ( isFinite() && !isZero() ) {
- MAPM m = Decimal::roundHalfToEven( value_, precision.itod() );
- if ( value_ < 0 && m == 0 )
+ MAPM m(
+ Decimal::roundHalfToEven2(
+ Decimal::value_type( value_ ),
+ Decimal::value_type( precision.itod() )
+ )
+ );
+ if ( value_ < 0 && m.sign() == 0 )
result = neg_zero();
else {
char buf[200];
@@ -353,8 +395,8 @@
#if 1
// This is the "spec" implementation, i.e., it is an exact application of
// the spec in http://www.w3.org/TR/xpath-functions/#casting
- MAPM decimal_mapm = value_;
- decimal_mapm = decimal_mapm.round(precision_);
+ MAPM decimal_mapm( value_ );
+ decimal_mapm = decimal_mapm.round( precision_ );
return Decimal::toString(decimal_mapm, max_precision());
#else
std::stringstream stream;
=== modified file 'src/zorbatypes/floatimpl.h'
--- src/zorbatypes/floatimpl.h 2012-03-30 19:03:09 +0000
+++ src/zorbatypes/floatimpl.h 2012-04-16 15:38:09 +0000
@@ -30,11 +30,11 @@
#include "zorbatypes_decl.h"
#ifdef ZORBA_WITH_BIG_INTEGER
-# define TEMPLATE_DECL(T) /* nothing */
-# define INTEGER_IMPL(T) IntegerImpl
+# define TEMPLATE_DECL(I) /* nothing */
+# define INTEGER_IMPL(I) IntegerImpl
#else
-# define TEMPLATE_DECL(T) template<typename T>
-# define INTEGER_IMPL(T) IntegerImpl<T>
+# define TEMPLATE_DECL(I) template<typename I>
+# define INTEGER_IMPL(I) IntegerImpl<I>
#endif /* ZORBA_WITH_BIG_INTEGER */
namespace zorba {
@@ -56,23 +56,23 @@
////////// constructors /////////////////////////////////////////////////////
- FloatImpl( char );
- FloatImpl( signed char c );
- FloatImpl( short n );
- FloatImpl( int n = 0 );
- FloatImpl( long n );
- FloatImpl( long long n );
- FloatImpl( unsigned char c );
- FloatImpl( unsigned short n );
- FloatImpl( unsigned int n );
- FloatImpl( unsigned long n );
- FloatImpl( unsigned long long n );
- FloatImpl( float n );
- FloatImpl( double n );
- FloatImpl( Decimal const &d );
+ explicit FloatImpl( char );
+ explicit FloatImpl( signed char c );
+ explicit FloatImpl( short n );
+ explicit FloatImpl( int n = 0 );
+ explicit FloatImpl( long n );
+ explicit FloatImpl( long long n );
+ explicit FloatImpl( unsigned char c );
+ explicit FloatImpl( unsigned short n );
+ explicit FloatImpl( unsigned int n );
+ explicit FloatImpl( unsigned long n );
+ explicit FloatImpl( unsigned long long n );
+ explicit FloatImpl( float n );
+ explicit FloatImpl( double n );
+ explicit FloatImpl( Decimal const &d );
- TEMPLATE_DECL(T)
- FloatImpl( INTEGER_IMPL(T) const &i );
+ TEMPLATE_DECL(IntType)
+ explicit FloatImpl( INTEGER_IMPL(IntType) const &i );
/**
* Constructs a %FloatImpl from a C string.
@@ -84,62 +84,74 @@
* @throw std::range_error if \a s contains a number that either underflows
* or overflows the smallest or largest representable floating point number.
*/
- FloatImpl( char const *s );
+ explicit FloatImpl( char const *s );
+ /**
+ * Constructs from another %FloatImpl even if its \c FloatType is different.
+ * (This subsumes the conventional copy constructor.)
+ *
+ * @tparam FloatType2 the floating-point type of \a f.
+ * @param f The %FloatImpl to copy from.
+ */
template<typename FloatType2>
FloatImpl( FloatImpl<FloatType2> const &f );
////////// assignment operators /////////////////////////////////////////////
+ /**
+ * Assign from a %FloatImpl even if its \c FloatType is different.
+ * (This subsumes the conventional assignment operator.)
+ *
+ * @tparam FloatType2 the floating-point type of \a f.
+ * @param f The %FloatImpl to assign from.
+ * @return Returns \c *this.
+ */
+ template<typename FloatType2>
+ FloatImpl& operator=( FloatImpl<FloatType2> const &f );
+
+ /**
+ * For every built-in arithmetic type A, assign to this %FloatImpl.
+ *
+ * @tparam A The built-in arithmetic type.
+ * @param n The arithmetic value to assign.
+ * @return Returns \c *this.
+ */
template<typename A>
typename std::enable_if<ZORBA_TR1_NS::is_arithmetic<A>::value,
FloatImpl&>::type
operator=( A n );
- template<typename FloatType2>
- FloatImpl& operator=( FloatImpl<FloatType2> const &f );
+ FloatImpl& operator=( char const *s );
+ FloatImpl& operator=( Decimal const &d );
+
+ TEMPLATE_DECL(I)
+ FloatImpl& operator=( INTEGER_IMPL(I) const &i );
////////// arithmetic operators /////////////////////////////////////////////
- template<typename A>
- typename std::enable_if<ZORBA_TR1_NS::is_arithmetic<A>::value,
- FloatImpl&>::type
- operator+=( A n );
-
- template<typename A>
- typename std::enable_if<ZORBA_TR1_NS::is_arithmetic<A>::value,
- FloatImpl&>::type
- operator-=( A n );
-
- template<typename A>
- typename std::enable_if<ZORBA_TR1_NS::is_arithmetic<A>::value,
- FloatImpl&>::type
- operator*=( A n );
-
- template<typename A>
- typename std::enable_if<ZORBA_TR1_NS::is_arithmetic<A>::value,
- FloatImpl&>::type
- operator/=( A n );
-
- template<typename A>
- typename std::enable_if<ZORBA_TR1_NS::is_arithmetic<A>::value,
- FloatImpl&>::type
- operator%=( A n );
-
- template<typename FloatType2>
- FloatImpl& operator+=( FloatImpl<FloatType2> const &f );
-
- template<typename FloatType2>
- FloatImpl& operator-=( FloatImpl<FloatType2> const &f );
-
- template<typename FloatType2>
- FloatImpl& operator*=( FloatImpl<FloatType2> const &f );
-
- template<typename FloatType2>
- FloatImpl& operator/=( FloatImpl<FloatType2> const &f );
-
- template<typename FloatType2>
- FloatImpl& operator%=( FloatImpl<FloatType2> const &f );
+#define ZORBA_FLOAT_OP(OP) \
+ template<typename A> \
+ typename std::enable_if<ZORBA_TR1_NS::is_arithmetic<A>::value, \
+ FloatImpl&>::type \
+ operator OP( A n )
+
+ ZORBA_FLOAT_OP(+=);
+ ZORBA_FLOAT_OP(-=);
+ ZORBA_FLOAT_OP(*=);
+ ZORBA_FLOAT_OP(/=);
+ ZORBA_FLOAT_OP(%=);
+#undef ZORBA_FLOAT_OP
+
+#define ZORBA_FLOAT_OP(OP) \
+ template<typename FloatType2> \
+ FloatImpl& operator OP( FloatImpl<FloatType2> const &f )
+
+ ZORBA_FLOAT_OP(+=);
+ ZORBA_FLOAT_OP(-=);
+ ZORBA_FLOAT_OP(*=);
+ ZORBA_FLOAT_OP(/=);
+ ZORBA_FLOAT_OP(%=);
+#undef ZORBA_FLOAT_OP
FloatImpl operator-() const;
@@ -231,7 +243,7 @@
void parse( char const* );
bool parse_etc( char const* );
- TEMPLATE_DECL(T) friend class IntegerImpl;
+ TEMPLATE_DECL(I) friend class IntegerImpl;
friend class Decimal;
friend class FloatImpl<float>;
@@ -255,528 +267,524 @@
////////// constructors ///////////////////////////////////////////////////////
-template<typename FloatType> inline
-FloatImpl<FloatType>::FloatImpl( char c ) :
- value_( static_cast<value_type>( c ) ), precision_( max_precision() )
-{
-}
-
-template<typename FloatType> inline
-FloatImpl<FloatType>::FloatImpl( signed char c ) :
- value_( static_cast<value_type>( c ) ), precision_( max_precision() )
-{
-}
-
-template<typename FloatType> inline
-FloatImpl<FloatType>::FloatImpl( short n ) :
- value_( static_cast<value_type>( n ) ), precision_( max_precision() )
-{
-}
-
-template<typename FloatType> inline
-FloatImpl<FloatType>::FloatImpl( int n ) :
- value_( static_cast<value_type>( n ) ), precision_( max_precision() )
-{
-}
-
-template<typename FloatType> inline
-FloatImpl<FloatType>::FloatImpl( long n ) :
- value_( static_cast<value_type>( n ) ), precision_( max_precision() )
-{
-}
-
-template<typename FloatType> inline
-FloatImpl<FloatType>::FloatImpl( long long n ) :
- value_( static_cast<value_type>( n ) ), precision_( max_precision() )
-{
-}
-
-template<typename FloatType> inline
-FloatImpl<FloatType>::FloatImpl( unsigned char c ) :
- value_( static_cast<value_type>( c ) ), precision_( max_precision() )
-{
-}
-
-template<typename FloatType> inline
-FloatImpl<FloatType>::FloatImpl( unsigned short n ) :
- value_( static_cast<value_type>( n ) ), precision_( max_precision() )
-{
-}
-
-template<typename FloatType> inline
-FloatImpl<FloatType>::FloatImpl( unsigned int n ) :
- value_( static_cast<value_type>( n ) ), precision_( max_precision() )
-{
-}
-
-template<typename FloatType> inline
-FloatImpl<FloatType>::FloatImpl( unsigned long n ) :
- value_( static_cast<value_type>( n ) ), precision_( max_precision() )
-{
-}
-
-template<typename FloatType> inline
-FloatImpl<FloatType>::FloatImpl( unsigned long long n ) :
- value_( static_cast<value_type>( n ) ), precision_( max_precision() )
-{
-}
-
-template<typename FloatType> inline
-FloatImpl<FloatType>::FloatImpl( float n ) :
- value_( static_cast<value_type>( n ) ), precision_( max_precision() )
-{
-}
-
-template<typename FloatType> inline
-FloatImpl<FloatType>::FloatImpl( double n ) :
- value_( static_cast<value_type>( n ) ), precision_( max_precision() )
-{
-}
-
-template<typename FloatType> inline
-FloatImpl<FloatType>::FloatImpl( char const *s ) {
+template<typename F>
+inline FloatImpl<F>::FloatImpl( char c ) :
+ value_( static_cast<F>( c ) ), precision_( max_precision() )
+{
+}
+
+template<typename F>
+inline FloatImpl<F>::FloatImpl( signed char c ) :
+ value_( static_cast<F>( c ) ), precision_( max_precision() )
+{
+}
+
+template<typename F>
+inline FloatImpl<F>::FloatImpl( short n ) :
+ value_( static_cast<F>( n ) ), precision_( max_precision() )
+{
+}
+
+template<typename F>
+inline FloatImpl<F>::FloatImpl( int n ) :
+ value_( static_cast<F>( n ) ), precision_( max_precision() )
+{
+}
+
+template<typename F>
+inline FloatImpl<F>::FloatImpl( long n ) :
+ value_( static_cast<F>( n ) ), precision_( max_precision() )
+{
+}
+
+template<typename F>
+inline FloatImpl<F>::FloatImpl( long long n ) :
+ value_( static_cast<F>( n ) ), precision_( max_precision() )
+{
+}
+
+template<typename F>
+inline FloatImpl<F>::FloatImpl( unsigned char c ) :
+ value_( static_cast<F>( c ) ), precision_( max_precision() )
+{
+}
+
+template<typename F>
+inline FloatImpl<F>::FloatImpl( unsigned short n ) :
+ value_( static_cast<F>( n ) ), precision_( max_precision() )
+{
+}
+
+template<typename F>
+inline FloatImpl<F>::FloatImpl( unsigned int n ) :
+ value_( static_cast<F>( n ) ), precision_( max_precision() )
+{
+}
+
+template<typename F>
+inline FloatImpl<F>::FloatImpl( unsigned long n ) :
+ value_( static_cast<F>( n ) ), precision_( max_precision() )
+{
+}
+
+template<typename F>
+inline FloatImpl<F>::FloatImpl( unsigned long long n ) :
+ value_( static_cast<F>( n ) ), precision_( max_precision() )
+{
+}
+
+template<typename F>
+inline FloatImpl<F>::FloatImpl( float n ) :
+ value_( static_cast<F>( n ) ), precision_( max_precision() )
+{
+}
+
+template<typename F>
+inline FloatImpl<F>::FloatImpl( double n ) :
+ value_( static_cast<F>( n ) ), precision_( max_precision() )
+{
+}
+
+template<typename F>
+inline FloatImpl<F>::FloatImpl( char const *s ) {
parse( s );
}
-template<typename FloatType>
-template<typename FloatType2>
-inline FloatImpl<FloatType>::FloatImpl( FloatImpl<FloatType2> const &f ) :
- value_( static_cast<value_type>( f.value_ ) ), precision_( max_precision() )
+template<typename F> template<typename G>
+inline FloatImpl<F>::FloatImpl( FloatImpl<G> const &f ) :
+ value_( static_cast<F>( f.value_ ) ), precision_( max_precision() )
{
}
-template<typename FloatType>
-inline FloatImpl<FloatType>::FloatImpl( value_type v, precision_type p ) :
+template<typename F>
+inline FloatImpl<F>::FloatImpl( value_type v, precision_type p ) :
value_( v ), precision_( p )
{
}
////////// assignment operators ///////////////////////////////////////////////
-template<typename T>
-template<typename A> inline
+template<typename F> template<typename G>
+inline FloatImpl<F>& FloatImpl<F>::operator=( FloatImpl<G> const &f ) {
+ value_ = static_cast<F>( f.value_ );
+ precision_ = max_precision();
+ return *this;
+}
+
+template<typename F> template<typename A> inline
typename std::enable_if<ZORBA_TR1_NS::is_arithmetic<A>::value,
- FloatImpl<T>&>::type
-FloatImpl<T>::operator=( A n ) {
- value_ = static_cast<value_type>( n );
+ FloatImpl<F>&>::type
+FloatImpl<F>::operator=( A n ) {
+ value_ = static_cast<F>( n );
precision_ = max_precision();
return *this;
}
-template<typename T>
-template<typename U>
-inline FloatImpl<T>& FloatImpl<T>::operator=( FloatImpl<U> const &f ) {
- value_ = static_cast<value_type>( f.value_ );
- precision_ = max_precision();
+template<typename F>
+inline FloatImpl<F>& FloatImpl<F>::operator=( char const *s ) {
+ parse( s );
return *this;
}
////////// arithmetic operators ///////////////////////////////////////////////
-#define ZORBA_DEF_FLOATIMPL_OP(OP) \
- template<typename T,typename A> inline \
+#define ZORBA_FLOAT_OP(OP) \
+ template<typename F,typename A> inline \
typename std::enable_if<ZORBA_TR1_NS::is_arithmetic<A>::value, \
- FloatImpl<T> >::type \
- operator OP( FloatImpl<T> const &f, A n ) { \
- return FloatImpl<T>( f.getNumber() OP static_cast<T>( n ) ); \
+ FloatImpl<F> >::type \
+ operator OP( FloatImpl<F> const &f, A n ) { \
+ return FloatImpl<F>( f.getNumber() OP static_cast<F>( n ) ); \
} \
- template<typename T,typename A> inline \
- typename std::enable_if<ZORBA_TR1_NS::is_arithmetic<A>::value, \
- FloatImpl<T> >::type \
- operator OP( A n, FloatImpl<T> const &f ) { \
- return FloatImpl<T>( static_cast<T>( n ) OP f.getNumber() ); \
- }
-
-ZORBA_DEF_FLOATIMPL_OP( + )
-ZORBA_DEF_FLOATIMPL_OP( - )
-ZORBA_DEF_FLOATIMPL_OP( * )
-ZORBA_DEF_FLOATIMPL_OP( / )
-
-#undef ZORBA_DEF_FLOATIMPL_OP
-
-template<typename T,typename A> inline
-typename std::enable_if<ZORBA_TR1_NS::is_arithmetic<A>::value,
- FloatImpl<T> >::type
-operator%( FloatImpl<T> const &f, A n ) {
- return FloatImpl<T>( std::fmod( f.getNumber(), static_cast<T>( n ) ) );
-}
-
-template<typename T,typename A> inline
-typename std::enable_if<ZORBA_TR1_NS::is_arithmetic<A>::value,
- FloatImpl<T> >::type
-operator%( A n, FloatImpl<T> const &f ) {
- return FloatImpl<T>( std::fmod( static_cast<T>( n ), f.getNumber() ) );
-}
-
-#define ZORBA_DEF_FLOATIMPL_OP(OP) \
- template<typename T> inline \
- FloatImpl<T> operator OP( FloatImpl<T> const &f, FloatImpl<T> const &g ) { \
- return FloatImpl<T>( f.getNumber() OP g.getNumber() ); \
- }
-
-ZORBA_DEF_FLOATIMPL_OP( + )
-ZORBA_DEF_FLOATIMPL_OP( - )
-ZORBA_DEF_FLOATIMPL_OP( * )
-ZORBA_DEF_FLOATIMPL_OP( / )
-
-#undef ZORBA_DEF_FLOATIMPL_OP
-
-template<typename T> inline
-FloatImpl<T> operator%( FloatImpl<T> const &f, FloatImpl<T> const &g ) {
- return FloatImpl<T>( std::fmod( f.getNumber(), g.getNumber() ) );
-}
-
-#define ZORBA_DEF_FLOATIMPL_OP(OP) \
- template<typename T> \
- template<typename A> inline \
- typename std::enable_if<ZORBA_TR1_NS::is_arithmetic<A>::value, \
- FloatImpl<T>&>::type \
- FloatImpl<T>::operator OP( A n ) { \
- value_ OP static_cast<value_type>( n ); \
+ \
+ template<typename F,typename A> inline \
+ typename std::enable_if<ZORBA_TR1_NS::is_arithmetic<A>::value, \
+ FloatImpl<F> >::type \
+ operator OP( A n, FloatImpl<F> const &f ) { \
+ return FloatImpl<F>( static_cast<F>( n ) OP f.getNumber() ); \
+ }
+
+ZORBA_FLOAT_OP(+)
+ZORBA_FLOAT_OP(-)
+ZORBA_FLOAT_OP(*)
+ZORBA_FLOAT_OP(/)
+#undef ZORBA_FLOAT_OP
+
+template<typename F,typename A> inline
+typename std::enable_if<ZORBA_TR1_NS::is_arithmetic<A>::value,
+ FloatImpl<F> >::type
+operator%( FloatImpl<F> const &f, A n ) {
+ return FloatImpl<F>( std::fmod( f.getNumber(), static_cast<F>( n ) ) );
+}
+
+template<typename F,typename A> inline
+typename std::enable_if<ZORBA_TR1_NS::is_arithmetic<A>::value,
+ FloatImpl<F> >::type
+operator%( A n, FloatImpl<F> const &f ) {
+ return FloatImpl<F>( std::fmod( static_cast<F>( n ), f.getNumber() ) );
+}
+
+#define ZORBA_FLOAT_OP(OP) \
+ template<typename F> inline \
+ FloatImpl<F> operator OP( FloatImpl<F> const &f, FloatImpl<F> const &g ) { \
+ return FloatImpl<F>( f.getNumber() OP g.getNumber() ); \
+ }
+
+ZORBA_FLOAT_OP(+)
+ZORBA_FLOAT_OP(-)
+ZORBA_FLOAT_OP(*)
+ZORBA_FLOAT_OP(/)
+#undef ZORBA_FLOAT_OP
+
+template<typename F>
+inline FloatImpl<F> operator%( FloatImpl<F> const &f, FloatImpl<F> const &g ) {
+ return FloatImpl<F>( std::fmod( f.getNumber(), g.getNumber() ) );
+}
+
+#define ZORBA_FLOAT_OP(OP) \
+ template<typename F> template<typename A> inline \
+ typename std::enable_if<ZORBA_TR1_NS::is_arithmetic<A>::value, \
+ FloatImpl<F>&>::type \
+ FloatImpl<F>::operator OP( A n ) { \
+ value_ OP static_cast<F>( n ); \
return *this; \
}
-ZORBA_DEF_FLOATIMPL_OP( += )
-ZORBA_DEF_FLOATIMPL_OP( -= )
-ZORBA_DEF_FLOATIMPL_OP( *= )
-ZORBA_DEF_FLOATIMPL_OP( /= )
-ZORBA_DEF_FLOATIMPL_OP( %= )
-
-#undef ZORBA_DEF_FLOATIMPL_OP
-
-#define ZORBA_DEF_FLOATIMPL_OP(OP) \
- template<typename T> \
- template<typename U> \
- inline FloatImpl<T>& FloatImpl<T>::operator OP( FloatImpl<U> const &f ) { \
- value_ OP static_cast<value_type>( f.value_ ); \
+ZORBA_FLOAT_OP(+=)
+ZORBA_FLOAT_OP(-=)
+ZORBA_FLOAT_OP(*=)
+ZORBA_FLOAT_OP(/=)
+ZORBA_FLOAT_OP(%=)
+#undef ZORBA_FLOAT_OP
+
+#define ZORBA_FLOAT_OP(OP) \
+ template<typename F> template<typename G> \
+ inline FloatImpl<F>& FloatImpl<F>::operator OP( FloatImpl<G> const &f ) { \
+ value_ OP static_cast<F>( f.value_ ); \
return *this; \
}
-ZORBA_DEF_FLOATIMPL_OP( += )
-ZORBA_DEF_FLOATIMPL_OP( -= )
-ZORBA_DEF_FLOATIMPL_OP( *= )
-ZORBA_DEF_FLOATIMPL_OP( /= )
-ZORBA_DEF_FLOATIMPL_OP( %= )
-
-#undef ZORBA_DEF_FLOATIMPL_OP
-
-template<typename FloatType>
-inline FloatImpl<FloatType> FloatImpl<FloatType>::operator-() const {
- return FloatImpl<FloatType>( -value_, precision_ );
-}
-
-inline Double operator+( Double const &d, Float const &f ) {
- return d.getNumber() + f.getNumber();
-}
-
-inline Double operator+( Float const &f, Double const &d ) {
- return f.getNumber() + d.getNumber();
-}
-
-inline Double operator-( Double const &d, Float const &f ) {
- return d.getNumber() - f.getNumber();
-}
-
-inline Double operator-( Float const &f, Double const &d ) {
- return f.getNumber() - d.getNumber();
-}
-
-inline Double operator*( Double const &d, Float const &f ) {
- return d.getNumber() * f.getNumber();
-}
-
-inline Double operator*( Float const &f, Double const &d ) {
- return f.getNumber() * d.getNumber();
-}
-
-inline Double operator/( Double const &d, Float const &f ) {
- return d.getNumber() / f.getNumber();
-}
-
-inline Double operator/( Float const &f, Double const &d ) {
- return f.getNumber() / d.getNumber();
-}
+ZORBA_FLOAT_OP(+=)
+ZORBA_FLOAT_OP(-=)
+ZORBA_FLOAT_OP(*=)
+ZORBA_FLOAT_OP(/=)
+#undef ZORBA_FLOAT_OP
+
+template<typename F> template<typename G>
+inline FloatImpl<F>& FloatImpl<F>::operator%=( FloatImpl<G> const &f ) {
+ value_ = std::fmod( value_, static_cast<F>( f.value_ ) );
+ return *this;
+}
+
+template<typename F>
+inline FloatImpl<F> FloatImpl<F>::operator-() const {
+ return FloatImpl<F>( -value_, precision_ );
+}
+
+#define ZORBA_FLOAT_OP(OP) \
+ inline Double operator OP( Double const &d, Float const &f ) { \
+ return Double( d.getNumber() OP f.getNumber() ); \
+ } \
+ inline Double operator OP( Float const &f, Double const &d ) { \
+ return Double( f.getNumber() OP d.getNumber() ); \
+ }
+
+ZORBA_FLOAT_OP(+)
+ZORBA_FLOAT_OP(-)
+ZORBA_FLOAT_OP(*)
+ZORBA_FLOAT_OP(/)
+#undef ZORBA_FLOAT_OP
inline Double operator%( Double const &d, Float const &f ) {
- return std::fmod( d.getNumber(), static_cast<double>( f.getNumber() ) );
+ return Double(
+ std::fmod( d.getNumber(), static_cast<double>( f.getNumber() ) )
+ );
}
inline Double operator%( Float const &f, Double const &d ) {
- return std::fmod( static_cast<double>( f.getNumber() ), d.getNumber() );
+ return Double(
+ std::fmod( static_cast<double>( f.getNumber() ), d.getNumber() )
+ );
}
////////// relational operators ///////////////////////////////////////////////
-template<typename T,typename U>
-inline bool operator==( FloatImpl<T> const &f, FloatImpl<U> const &g ) {
+template<typename F,typename G>
+inline bool operator==( FloatImpl<F> const &f, FloatImpl<G> const &g ) {
return f.getNumber() == g.getNumber();
}
-template<typename T,typename U>
-inline bool operator!=( FloatImpl<T> const &f, FloatImpl<U> const &g ) {
+template<typename F,typename G>
+inline bool operator!=( FloatImpl<F> const &f, FloatImpl<G> const &g ) {
return f.getNumber() != g.getNumber();
}
-template<typename T,typename U>
-inline bool operator<( FloatImpl<T> const &f, FloatImpl<U> const &g ) {
+template<typename F,typename G>
+inline bool operator<( FloatImpl<F> const &f, FloatImpl<G> const &g ) {
return f.getNumber() < g.getNumber();
}
-template<typename T,typename U>
-inline bool operator<=( FloatImpl<T> const &f, FloatImpl<U> const &g ) {
+template<typename F,typename G>
+inline bool operator<=( FloatImpl<F> const &f, FloatImpl<G> const &g ) {
return !f.isNaN() && !g.isNaN() && f.getNumber() <= g.getNumber();
}
-template<typename T,typename U>
-inline bool operator>( FloatImpl<T> const &f, FloatImpl<U> const &g ) {
+template<typename F,typename G>
+inline bool operator>( FloatImpl<F> const &f, FloatImpl<G> const &g ) {
return f.getNumber() > g.getNumber();
}
-template<typename T,typename U>
-inline bool operator>=( FloatImpl<T> const &f, FloatImpl<U> const &g ) {
+template<typename F,typename G>
+inline bool operator>=( FloatImpl<F> const &f, FloatImpl<G> const &g ) {
return !f.isNaN() && !g.isNaN() && f.getNumber() >= g.getNumber();
}
-template<typename T>
-inline bool operator==( FloatImpl<T> const &f, double d ) {
+template<typename F>
+inline bool operator==( FloatImpl<F> const &f, double d ) {
return f.getNumber() == d;
}
-template<typename T>
-inline bool operator==( double d, FloatImpl<T> const &f ) {
+template<typename F>
+inline bool operator==( double d, FloatImpl<F> const &f ) {
return d = f.getNumber();
}
-template<typename T>
-inline bool operator!=( FloatImpl<T> const &f, double d ) {
- return f.getNumber() != d;
-}
-
-template<typename T>
-inline bool operator!=( double d, FloatImpl<T> const &f ) {
- return f.getNumber() != d;
-}
-
-template<typename T>
-inline bool operator<( FloatImpl<T> const &f, double d ) {
+template<typename F>
+inline bool operator!=( FloatImpl<F> const &f, double d ) {
+ return f.getNumber() != d;
+}
+
+template<typename F>
+inline bool operator!=( double d, FloatImpl<F> const &f ) {
+ return f.getNumber() != d;
+}
+
+template<typename F>
+inline bool operator<( FloatImpl<F> const &f, double d ) {
return f.getNumber() < d;
}
-template<typename T>
-inline bool operator<( double d, FloatImpl<T> const &f ) {
+template<typename F>
+inline bool operator<( double d, FloatImpl<F> const &f ) {
return d < f.getNumber();
}
-template<typename T>
-inline bool operator<=( FloatImpl<T> const &f, double d ) {
+template<typename F>
+inline bool operator<=( FloatImpl<F> const &f, double d ) {
return !f.isNaN() && d == d && f.getNumber() <= d;
}
-template<typename T>
-inline bool operator<=( double d, FloatImpl<T> const &f ) {
+template<typename F>
+inline bool operator<=( double d, FloatImpl<F> const &f ) {
return d == d && !f.isNaN() && d <= f.getNumber();
}
-template<typename T>
-inline bool operator>( FloatImpl<T> const &f, double d ) {
+template<typename F>
+inline bool operator>( FloatImpl<F> const &f, double d ) {
return f.getNumber() > d;
}
-template<typename T>
-inline bool operator>( double d, FloatImpl<T> const &f ) {
+template<typename F>
+inline bool operator>( double d, FloatImpl<F> const &f ) {
return d > f.getNumber();
}
-template<typename T>
-inline bool operator>=( FloatImpl<T> const &f, double d ) {
+template<typename F>
+inline bool operator>=( FloatImpl<F> const &f, double d ) {
return !f.isNaN() && d == d && f.getNumber() >= d;
}
-template<typename T>
-inline bool operator>=( double d, FloatImpl<T> const &f ) {
+template<typename F>
+inline bool operator>=( double d, FloatImpl<F> const &f ) {
return d == d && !f.isNaN() && d >= f.getNumber();
}
////////// math functions /////////////////////////////////////////////////////
-template<typename FloatType> inline FloatImpl<FloatType>
-FloatImpl<FloatType>::acosh() const {
- // formula from www.mathworks.com
- return std::log( value_ + std::sqrt( value_ * value_ - 1 ) );
-}
-
-template<typename FloatType> inline FloatImpl<FloatType>
-FloatImpl<FloatType>::asinh() const {
- // formula from www.mathworks.com
- return std::log( value_ + std::sqrt( value_ * value_ + 1 ) );
-}
-
-template<typename FloatType> inline FloatImpl<FloatType>
-FloatImpl<FloatType>::atan() const {
- return std::atan( value_ );
-}
-
-template<typename FloatType> inline FloatImpl<FloatType>
-FloatImpl<FloatType>::atanh() const {
- // formula from www.mathworks.com
- return 0.5 * std::log( (1 + value_) / (1 - value_) );
-}
-
-template<typename FloatType> inline FloatImpl<FloatType>
-FloatImpl<FloatType>::atan2( double x ) const {
- return std::atan2( value_, static_cast<value_type>( x ) );
-}
-
-template<typename FloatType> inline FloatImpl<FloatType>
-FloatImpl<FloatType>::atan2( FloatImpl<FloatType> const &x ) const {
- return atan2( x.value_ );
-}
-
-template<typename FloatType> inline FloatImpl<FloatType>
-FloatImpl<FloatType>::ceil() const {
- return std::ceil( value_ );
-}
-
-template<typename FloatType> inline FloatImpl<FloatType>
-FloatImpl<FloatType>::cos() const {
- return std::cos( value_ );
-}
-
-template<typename FloatType> inline FloatImpl<FloatType>
-FloatImpl<FloatType>::cosh() const {
- return std::cosh( value_ );
-}
-
-template<typename FloatType> inline FloatImpl<FloatType>
-FloatImpl<FloatType>::exp() const {
- return std::exp( value_ );
-}
-
-template<typename FloatType> inline FloatImpl<FloatType>
-FloatImpl<FloatType>::exp10() const {
- return std::pow( 10, value_ );
-}
-
-template<typename FloatType> inline FloatImpl<FloatType>
-FloatImpl<FloatType>::floor() const {
- return std::floor( value_ );
-}
-
-template<typename FloatType> inline FloatImpl<FloatType>
-FloatImpl<FloatType>::fmod( double d ) const {
- return std::fmod( value_, static_cast<value_type>( d ) );
-}
-
-template<typename FloatType> inline FloatImpl<FloatType>
-FloatImpl<FloatType>::fmod( FloatImpl<FloatType> const &f ) const {
- return fmod( f.value_ );
-}
-
-template<typename FloatType>
-FloatImpl<FloatType> FloatImpl<FloatType>::log() const {
- return value_ < 0 ? nan() : FloatImpl<FloatType>( std::log( value_ ) );
-}
-
-template<typename FloatType>
-FloatImpl<FloatType> FloatImpl<FloatType>::log10() const {
- return value_ < 0 ? nan() : FloatImpl<FloatType>( std::log10( value_ ) );
-}
-
-template<typename FloatType> inline FloatImpl<FloatType>
-FloatImpl<FloatType>::pow( int p ) const {
- return std::pow( value_, p );
-}
-
-template<typename FloatType> inline FloatImpl<FloatType>
-FloatImpl<FloatType>::pow( FloatImpl<FloatType> const &p ) const {
- return p.isNaN() ? value_ : std::pow( value_, p.value_ );
-}
-
-template<typename FloatType> inline FloatImpl<FloatType>
-FloatImpl<FloatType>::sin() const {
- return std::sin( value_ );
-}
-
-template<typename FloatType> inline FloatImpl<FloatType>
-FloatImpl<FloatType>::sinh() const {
- return std::sinh( value_ );
-}
-
-template<typename FloatType> inline FloatImpl<FloatType>
-FloatImpl<FloatType>::sqrt() const {
+template<typename F>
+inline FloatImpl<F> FloatImpl<F>::acosh() const {
+ // formula from www.mathworks.com
+ return FloatImpl<F>(
+ std::log( value_ + std::sqrt( value_ * value_ - 1 ) )
+ );
+}
+
+template<typename F>
+inline FloatImpl<F> FloatImpl<F>::asinh() const {
+ // formula from www.mathworks.com
+ return FloatImpl<F>(
+ std::log( value_ + std::sqrt( value_ * value_ + 1 ) )
+ );
+}
+
+template<typename F>
+inline FloatImpl<F> FloatImpl<F>::atan() const {
+ return FloatImpl<F>( std::atan( value_ ) );
+}
+
+template<typename F>
+inline FloatImpl<F> FloatImpl<F>::atanh() const {
+ // formula from www.mathworks.com
+ return FloatImpl<F>( 0.5 * std::log( (1 + value_) / (1 - value_) ) );
+}
+
+template<typename F>
+inline FloatImpl<F> FloatImpl<F>::atan2( double x ) const {
+ return FloatImpl<F>( std::atan2( value_, static_cast<F>( x ) ) );
+}
+
+template<typename F>
+inline FloatImpl<F> FloatImpl<F>::atan2( FloatImpl<F> const &x ) const {
+ return FloatImpl<F>( atan2( x.value_ ) );
+}
+
+template<typename F>
+inline FloatImpl<F> FloatImpl<F>::ceil() const {
+ return FloatImpl<F>( std::ceil( value_ ) );
+}
+
+template<typename F>
+inline FloatImpl<F> FloatImpl<F>::cos() const {
+ return FloatImpl<F>( std::cos( value_ ) );
+}
+
+template<typename F>
+inline FloatImpl<F> FloatImpl<F>::cosh() const {
+ return FloatImpl<F>( std::cosh( value_ ) );
+}
+
+template<typename F>
+inline FloatImpl<F> FloatImpl<F>::exp() const {
+ return FloatImpl<F>( std::exp( value_ ) );
+}
+
+template<typename F>
+inline FloatImpl<F> FloatImpl<F>::exp10() const {
+ return FloatImpl<F>( std::pow( 10, value_ ) );
+}
+
+template<typename F>
+inline FloatImpl<F> FloatImpl<F>::floor() const {
+ return FloatImpl<F>( std::floor( value_ ) );
+}
+
+template<typename F>
+inline FloatImpl<F> FloatImpl<F>::fmod( double d ) const {
+ return FloatImpl<F>( std::fmod( value_, static_cast<F>( d ) ) );
+}
+
+template<typename F>
+inline FloatImpl<F>
+FloatImpl<F>::fmod( FloatImpl<F> const &f ) const {
+ return FloatImpl<F>( fmod( f.value_ ) );
+}
+
+template<typename F>
+FloatImpl<F> FloatImpl<F>::log() const {
+ return value_ < 0 ? nan() : FloatImpl<F>( std::log( value_ ) );
+}
+
+template<typename F>
+FloatImpl<F> FloatImpl<F>::log10() const {
+ return value_ < 0 ? nan() : FloatImpl<F>( std::log10( value_ ) );
+}
+
+template<typename F>
+inline FloatImpl<F> FloatImpl<F>::pow( int p ) const {
+ return FloatImpl<F>( std::pow( value_, p ) );
+}
+
+template<typename F>
+inline FloatImpl<F>
+FloatImpl<F>::pow( FloatImpl<F> const &p ) const {
+ return FloatImpl<F>(
+ p.isNaN() ? value_ : std::pow( value_, p.value_ )
+ );
+}
+
+template<typename F>
+inline FloatImpl<F> FloatImpl<F>::sin() const {
+ return FloatImpl<F>( std::sin( value_ ) );
+}
+
+template<typename F>
+inline FloatImpl<F> FloatImpl<F>::sinh() const {
+ return FloatImpl<F>( std::sinh( value_ ) );
+}
+
+template<typename F>
+inline FloatImpl<F> FloatImpl<F>::sqrt() const {
return value_ < 0 ? nan() : FloatImpl( std::sqrt( value_ ) );
}
-template<typename FloatType> inline FloatImpl<FloatType>
-FloatImpl<FloatType>::tan() const {
- return std::tan( value_ );
+template<typename F>
+inline FloatImpl<F> FloatImpl<F>::tan() const {
+ return FloatImpl<F>( std::tan( value_ ) );
}
-template<typename FloatType> inline FloatImpl<FloatType>
-FloatImpl<FloatType>::tanh() const {
- return std::tanh( value_ );
+template<typename F>
+inline FloatImpl<F> FloatImpl<F>::tanh() const {
+ return FloatImpl<F>( std::tanh( value_ ) );
}
////////// miscellaneous //////////////////////////////////////////////////////
-template<typename T>
-template<typename U>
-inline int FloatImpl<T>::compare( FloatImpl<U> const &f ) const {
+template<typename F> template<typename G>
+inline int FloatImpl<F>::compare( FloatImpl<G> const &f ) const {
return value_ < f.value_ ? -1 : value_ > f.value_ ? 1 : 0;
}
-template<typename FloatType>
-inline uint32_t FloatImpl<FloatType>::hash() const {
+template<typename F>
+inline uint32_t FloatImpl<F>::hash() const {
return static_cast<uint32_t>( value_ );
}
-template<typename FloatType>
-inline bool FloatImpl<FloatType>::isNeg() const {
+template<typename F>
+inline bool FloatImpl<F>::isNeg() const {
return value_ < 0;
}
-template<typename FloatType>
-inline bool FloatImpl<FloatType>::isPos() const {
+template<typename F>
+inline bool FloatImpl<F>::isPos() const {
return value_ > 0;
}
-template<typename FloatType>
-inline bool FloatImpl<FloatType>::isPosZero() const {
+template<typename F>
+inline bool FloatImpl<F>::isPosZero() const {
return value_ == 0 && !isNegZero();
}
-template<typename FloatType>
-inline bool FloatImpl<FloatType>::isNaN() const {
+template<typename F>
+inline bool FloatImpl<F>::isNaN() const {
return value_ != value_;
}
-template<typename FloatType>
-inline bool FloatImpl<FloatType>::isNegInf() const {
- return value_ == -std::numeric_limits<FloatType>::infinity();
-}
-
-template<typename FloatType>
-inline bool FloatImpl<FloatType>::isPosInf() const {
- return value_ == std::numeric_limits<FloatType>::infinity();
-}
-
-template<typename FloatType>
-inline bool FloatImpl<FloatType>::isFinite() const {
+template<typename F>
+inline bool FloatImpl<F>::isNegInf() const {
+ return value_ == -std::numeric_limits<F>::infinity();
+}
+
+template<typename F>
+inline bool FloatImpl<F>::isPosInf() const {
+ return value_ == std::numeric_limits<F>::infinity();
+}
+
+template<typename F>
+inline bool FloatImpl<F>::isFinite() const {
return !isNaN() && !isPosInf() && !isNegInf();
}
-template<typename FloatType>
-inline bool FloatImpl<FloatType>::isInteger() const {
+template<typename F>
+inline bool FloatImpl<F>::isInteger() const {
return isFinite() && ::floor( value_ ) == value_;
}
-template <typename FloatType>
-inline bool FloatImpl<FloatType>::isZero() const {
+template <typename F>
+inline bool FloatImpl<F>::isZero() const {
return value_ == 0;
}
-template<typename FloatType> inline
-std::ostream& operator<<( std::ostream &os, FloatImpl<FloatType> const &f ) {
+template<typename F>
+inline std::ostream& operator<<( std::ostream &os, FloatImpl<F> const &f ) {
return os << f.toString();
}
=== modified file 'src/zorbatypes/integer.cpp'
--- src/zorbatypes/integer.cpp 2012-03-30 19:03:09 +0000
+++ src/zorbatypes/integer.cpp 2012-04-16 15:38:09 +0000
@@ -230,13 +230,13 @@
TEMPLATE_DECL(T)
INTEGER_IMPL(T) INTEGER_IMPL(T)::round( IntegerImpl const &precision ) const {
- return IntegerImpl( Decimal::round( itod(), precision.itod() ) );
+ return IntegerImpl( Decimal::round2( itod(), precision.itod() ) );
}
TEMPLATE_DECL(T)
INTEGER_IMPL(T)
INTEGER_IMPL(T)::roundHalfToEven( IntegerImpl const &precision ) const {
- return IntegerImpl( Decimal::roundHalfToEven( itod(), precision.itod() ) );
+ return IntegerImpl( Decimal::roundHalfToEven2( itod(), precision.itod() ) );
}
////////// miscellaneous //////////////////////////////////////////////////////
=== modified file 'src/zorbatypes/integer.h'
--- src/zorbatypes/integer.h 2012-04-12 02:08:10 +0000
+++ src/zorbatypes/integer.h 2012-04-16 15:38:09 +0000
@@ -22,8 +22,8 @@
#include <limits>
#include <zorba/config.h>
+
#include "common/common.h"
-
#include "util/stl_util.h"
#include "m_apm.h"
@@ -32,25 +32,25 @@
#include "zstring.h"
#ifdef ZORBA_WITH_BIG_INTEGER
-# define TEMPLATE_DECL(T) /* nothing */
-# define INTEGER_IMPL(T) IntegerImpl
+# define TEMPLATE_DECL(I) /* nothing */
+# define TEMPLATE_DECL2(I,A) template<typename A>
+# define INTEGER_IMPL(I) IntegerImpl
#else
-# define TEMPLATE_DECL(T) template<typename T>
-# define INTEGER_IMPL(T) IntegerImpl<T>
+# define TEMPLATE_DECL(I) template<typename I>
+# define TEMPLATE_DECL2(I,A) template<typename I,typename A>
+# define INTEGER_IMPL(I) IntegerImpl<I>
#endif /* ZORBA_WITH_BIG_INTEGER */
#define INTEGER_IMPL_LL INTEGER_IMPL(long long)
#define INTEGER_IMPL_ULL INTEGER_IMPL(unsigned long long)
namespace zorba {
-TEMPLATE_DECL(T)
+TEMPLATE_DECL(I)
class IntegerImpl;
-namespace serialization
-{
+namespace serialization {
class Archiver;
-
- TEMPLATE_DECL(T) void operator&( Archiver&, INTEGER_IMPL(T)& );
+ TEMPLATE_DECL(I) void operator&( Archiver&, INTEGER_IMPL(I)& );
}
///////////////////////////////////////////////////////////////////////////////
@@ -61,23 +61,20 @@
////////// constructors /////////////////////////////////////////////////////
- IntegerImpl( char c );
- IntegerImpl( signed char c );
- IntegerImpl( short n );
- IntegerImpl( int n = 0 );
- IntegerImpl( long n );
- IntegerImpl( long long n );
- IntegerImpl( unsigned char c );
- IntegerImpl( unsigned short n );
- IntegerImpl( unsigned int n );
- IntegerImpl( unsigned long n );
- IntegerImpl( unsigned long long n );
- IntegerImpl( float n );
- IntegerImpl( double n );
- IntegerImpl( Decimal const &d );
-
- TEMPLATE_DECL(U)
- IntegerImpl( INTEGER_IMPL(U) const &i );
+ explicit IntegerImpl( char c );
+ explicit IntegerImpl( signed char c );
+ explicit IntegerImpl( short n );
+ explicit IntegerImpl( int n = 0 );
+ explicit IntegerImpl( long n );
+ explicit IntegerImpl( long long n );
+ explicit IntegerImpl( unsigned char c );
+ explicit IntegerImpl( unsigned short n );
+ explicit IntegerImpl( unsigned int n );
+ explicit IntegerImpl( unsigned long n );
+ explicit IntegerImpl( unsigned long long n );
+ explicit IntegerImpl( float n );
+ explicit IntegerImpl( double n );
+ explicit IntegerImpl( Decimal const &d );
/**
* Constructs an %IntegerImpl from a C string.
@@ -89,7 +86,7 @@
* or overflows the smallest or largest representable integer (only when not
* compiled with ZORBA_WITH_BIG_INTEGER).
*/
- IntegerImpl( char const *s );
+ explicit IntegerImpl( char const *s );
/**
* Constructs an %IntegerImpl from a Double.
@@ -97,7 +94,7 @@
* @param d The Double.
* @throw std::invalid_argument if \a d is not finite.
*/
- IntegerImpl( Double const &d );
+ explicit IntegerImpl( Double const &d );
/**
* Constructs an %IntegerImpl from a Float.
@@ -105,54 +102,113 @@
* @param f The Float.
* @throw std::invalid_argument if \a f is not finite.
*/
- IntegerImpl( Float const &f );
+ explicit IntegerImpl( Float const &f );
+
+ /**
+ * Constructs from another %IntegerImpl even if its \c IntType is different.
+ * (This subsumes the conventional copy constructor.)
+ *
+ * @tparam IntType2 the integer type of \a i.
+ * @param i The %IntegerImpl to copy from.
+ */
+ TEMPLATE_DECL(IntType2)
+ IntegerImpl( INTEGER_IMPL(IntType2) const &i );
////////// assignment operators /////////////////////////////////////////////
- IntegerImpl& operator=( char c );
- IntegerImpl& operator=( signed char c );
- IntegerImpl& operator=( short n );
- IntegerImpl& operator=( int n );
- IntegerImpl& operator=( long n );
- IntegerImpl& operator=( long long n );
- IntegerImpl& operator=( unsigned char c );
- IntegerImpl& operator=( unsigned short n );
- IntegerImpl& operator=( unsigned int n );
- IntegerImpl& operator=( unsigned long n );
- IntegerImpl& operator=( unsigned long long n );
- IntegerImpl& operator=( float n );
- IntegerImpl& operator=( double n );
+ /**
+ * Assign from an %IntegerImpl even if its \c IntType is different.
+ * (This subsumes the conventional assignment operator.)
+ *
+ * @tparam IntType2 the integer type of \a i.
+ * @param i The %IntegerImpl to assign from.
+ * @return Returns \c *this.
+ */
+ TEMPLATE_DECL(IntType2)
+ IntegerImpl& operator=( INTEGER_IMPL(IntType2) const &i );
+
+ /**
+ * For every built-in arithmetic type A, assign to this %IntegerImpl.
+ *
+ * @tparam A The built-in arithmetic type.
+ * @param n The arithmetic value to assign.
+ * @return Returns \c *this.
+ */
+ template<typename A>
+ typename std::enable_if<ZORBA_TR1_NS::is_arithmetic<A>::value,
+ IntegerImpl&>::type
+ operator=( A n );
+
+ // These arithmetic types have to be special-cased.
+ IntegerImpl& operator=( long long );
+ IntegerImpl& operator=( unsigned long );
+ IntegerImpl& operator=( unsigned long long );
+
IntegerImpl& operator=( char const *s );
IntegerImpl& operator=( Decimal const &d );
IntegerImpl& operator=( Double const &d );
IntegerImpl& operator=( Float const &f );
- TEMPLATE_DECL(U)
- IntegerImpl& operator=( INTEGER_IMPL(U) const &i );
-
////////// arithmetic operators /////////////////////////////////////////////
#define ZORBA_INTEGER_OP(OP) \
- TEMPLATE_DECL(T) friend \
- INTEGER_IMPL(T) operator OP( INTEGER_IMPL(T) const&, \
- INTEGER_IMPL(T) const& ); \
- TEMPLATE_DECL(T) friend \
- Decimal operator OP( INTEGER_IMPL(T) const&, Decimal const& ); \
- TEMPLATE_DECL(T) friend \
- Decimal operator OP( Decimal const&, INTEGER_IMPL(T) const& )
-
- ZORBA_INTEGER_OP(+);
- ZORBA_INTEGER_OP(-);
- ZORBA_INTEGER_OP(*);
- ZORBA_INTEGER_OP(/);
- ZORBA_INTEGER_OP(%);
-#undef ZORBA_INTEGER_OP
-
- IntegerImpl& operator+=( IntegerImpl const& );
- IntegerImpl& operator-=( IntegerImpl const& );
- IntegerImpl& operator*=( IntegerImpl const& );
- IntegerImpl& operator/=( IntegerImpl const& );
- IntegerImpl& operator%=( IntegerImpl const& );
+ TEMPLATE_DECL(I) friend \
+ INTEGER_IMPL(I) operator OP( INTEGER_IMPL(I) const&, \
+ INTEGER_IMPL(I) const& ); \
+ \
+ TEMPLATE_DECL(I) friend \
+ Decimal operator OP( INTEGER_IMPL(I) const&, Decimal const& ); \
+ \
+ TEMPLATE_DECL(I) friend \
+ Decimal operator OP( Decimal const&, INTEGER_IMPL(I) const& )
+
+ ZORBA_INTEGER_OP(+);
+ ZORBA_INTEGER_OP(-);
+ ZORBA_INTEGER_OP(*);
+ ZORBA_INTEGER_OP(/);
+ ZORBA_INTEGER_OP(%);
+#undef ZORBA_INTEGER_OP
+
+#define ZORBA_INTEGER_OP(OP) \
+ TEMPLATE_DECL2(I,A) friend \
+ typename std::enable_if<ZORBA_TR1_NS::is_arithmetic<A>::value, \
+ INTEGER_IMPL(I)>::type \
+ operator OP( INTEGER_IMPL(I) const&, A ); \
+ \
+ TEMPLATE_DECL2(I,A) friend \
+ typename std::enable_if<ZORBA_TR1_NS::is_arithmetic<A>::value, \
+ INTEGER_IMPL(I)>::type \
+ operator OP( A, INTEGER_IMPL(I) const& )
+
+ ZORBA_INTEGER_OP(+);
+ ZORBA_INTEGER_OP(-);
+ ZORBA_INTEGER_OP(*);
+ ZORBA_INTEGER_OP(/);
+ ZORBA_INTEGER_OP(%);
+#undef ZORBA_INTEGER_OP
+
+#define ZORBA_INTEGER_OP(OP,TYPE) \
+ IntegerImpl& operator OP( TYPE )
+
+ ZORBA_INTEGER_OP(+=,IntegerImpl const&);
+ ZORBA_INTEGER_OP(-=,IntegerImpl const&);
+ ZORBA_INTEGER_OP(*=,IntegerImpl const&);
+ ZORBA_INTEGER_OP(/=,IntegerImpl const&);
+ ZORBA_INTEGER_OP(%=,IntegerImpl const&);
+#undef ZORBA_INTEGER_OP
+
+#define ZORBA_INTEGER_OP(OP) \
+ template<typename A> \
+ typename std::enable_if<ZORBA_TR1_NS::is_arithmetic<A>::value, \
+ IntegerImpl&>::type \
+ operator OP( A )
+
+ ZORBA_INTEGER_OP(+=);
+ ZORBA_INTEGER_OP(-=);
+ ZORBA_INTEGER_OP(*=);
+ ZORBA_INTEGER_OP(/=);
+ ZORBA_INTEGER_OP(%=);
+#undef ZORBA_INTEGER_OP
IntegerImpl operator-() const;
@@ -164,12 +220,31 @@
////////// relational operators /////////////////////////////////////////////
#define ZORBA_INTEGER_OP(OP) \
- TEMPLATE_DECL(T) friend \
- bool operator OP( INTEGER_IMPL(T) const&, INTEGER_IMPL(T) const& ); \
- TEMPLATE_DECL(T) friend \
- bool operator OP( INTEGER_IMPL(T) const&, Decimal const& ); \
- TEMPLATE_DECL(T) friend \
- bool operator OP( Decimal const&, INTEGER_IMPL(T) const& )
+ TEMPLATE_DECL(I) friend \
+ bool operator OP( INTEGER_IMPL(I) const&, INTEGER_IMPL(I) const& ); \
+ \
+ TEMPLATE_DECL(I) friend \
+ bool operator OP( INTEGER_IMPL(I) const&, Decimal const& ); \
+ \
+ TEMPLATE_DECL(I) friend \
+ bool operator OP( Decimal const&, INTEGER_IMPL(I) const& )
+
+ ZORBA_INTEGER_OP(==);
+ ZORBA_INTEGER_OP(!=);
+ ZORBA_INTEGER_OP(< );
+ ZORBA_INTEGER_OP(<=);
+ ZORBA_INTEGER_OP(> );
+ ZORBA_INTEGER_OP(>=);
+#undef ZORBA_INTEGER_OP
+
+#define ZORBA_INTEGER_OP(OP) \
+ TEMPLATE_DECL2(I,A) friend \
+ typename std::enable_if<ZORBA_TR1_NS::is_arithmetic<A>::value,bool>::type \
+ operator OP( INTEGER_IMPL(I) const&, A ); \
+ \
+ TEMPLATE_DECL2(I,A) friend \
+ typename std::enable_if<ZORBA_TR1_NS::is_arithmetic<A>::value,bool>::type \
+ operator OP( A, INTEGER_IMPL(I) const& )
ZORBA_INTEGER_OP(==);
ZORBA_INTEGER_OP(!=);
@@ -214,6 +289,11 @@
}
#ifdef ZORBA_WITH_BIG_INTEGER
+ template<typename T>
+ static value_type cast( T n ) {
+ return value_type( static_cast<long>( n ) );
+ }
+
static value_type ftoi( MAPM const &d ) {
return d.sign() >= 0 ? d.floor() : d.ceil();
}
@@ -222,6 +302,11 @@
return value_; // intentional no-op
}
#else
+ template<typename T>
+ static value_type cast( T n ) {
+ return static_cast<value_type>( n );
+ }
+
bool is_long() const;
static value_type ftoi( value_type v ) {
@@ -239,7 +324,7 @@
template<typename T> friend class FloatImpl;
#ifndef ZORBA_WITH_BIG_INTEGER
- template<typename U> friend class IntegerImpl;
+ template<typename T> friend class IntegerImpl;
#endif /* ZORBA_WITH_BIG_INTEGER */
friend xs_int to_xs_int( INTEGER_IMPL_LL const& );
@@ -247,8 +332,8 @@
friend xs_unsignedInt to_xs_unsignedInt( INTEGER_IMPL_LL const& );
friend xs_unsignedLong to_xs_unsignedLong( INTEGER_IMPL_LL const& );
- TEMPLATE_DECL(T) friend
- void serialization::operator&( serialization::Archiver&, INTEGER_IMPL(T)& );
+ TEMPLATE_DECL(I) friend
+ void serialization::operator&( serialization::Archiver&, INTEGER_IMPL(I)& );
};
typedef INTEGER_IMPL_LL Integer;
@@ -256,78 +341,78 @@
////////// constructors ///////////////////////////////////////////////////////
-TEMPLATE_DECL(T)
-inline INTEGER_IMPL(T)::IntegerImpl( char c ) :
- value_( static_cast<long>( c ) )
-{
-}
-
-TEMPLATE_DECL(T)
-inline INTEGER_IMPL(T)::IntegerImpl( signed char c ) :
- value_( static_cast<long>( c ) )
-{
-}
-
-TEMPLATE_DECL(T)
-inline INTEGER_IMPL(T)::IntegerImpl( short n ) :
- value_( static_cast<long>( n ) )
-{
-}
-
-TEMPLATE_DECL(T)
-inline INTEGER_IMPL(T)::IntegerImpl( int n ) :
- value_( static_cast<long>( n ) )
-{
-}
-
-TEMPLATE_DECL(T)
-inline INTEGER_IMPL(T)::IntegerImpl( long n ) :
- value_( n )
-{
-}
-
-#ifndef ZORBA_WITH_BIG_INTEGER
-TEMPLATE_DECL(T)
-inline INTEGER_IMPL(T)::IntegerImpl( long long n ) :
- value_( n )
-{
-}
-#endif /* ZORBA_WITH_BIG_INTEGER */
-
-TEMPLATE_DECL(T)
-inline INTEGER_IMPL(T)::IntegerImpl( unsigned char c ) :
- value_( static_cast<long>( c ) )
-{
-}
-
-TEMPLATE_DECL(T)
-inline INTEGER_IMPL(T)::IntegerImpl( unsigned short n ) :
- value_( static_cast<long>( n ) )
-{
-}
-
-TEMPLATE_DECL(T)
-inline INTEGER_IMPL(T)::IntegerImpl( unsigned int n ) :
- value_( static_cast<long>( n ) )
-{
-}
-
-#ifndef ZORBA_WITH_BIG_INTEGER
-TEMPLATE_DECL(T)
-inline INTEGER_IMPL(T)::IntegerImpl( unsigned long n ) :
- value_( static_cast<value_type>( n ) )
-{
-}
-
-TEMPLATE_DECL(T)
-inline INTEGER_IMPL(T)::IntegerImpl( unsigned long long n ) :
- value_( static_cast<value_type>( n ) )
-{
-}
-#endif /* ZORBA_WITH_BIG_INTEGER */
-
-TEMPLATE_DECL(T)
-inline INTEGER_IMPL(T)::IntegerImpl( float n ) :
+TEMPLATE_DECL(I)
+inline INTEGER_IMPL(I)::IntegerImpl( char c ) :
+ value_( static_cast<long>( c ) )
+{
+}
+
+TEMPLATE_DECL(I)
+inline INTEGER_IMPL(I)::IntegerImpl( signed char c ) :
+ value_( static_cast<long>( c ) )
+{
+}
+
+TEMPLATE_DECL(I)
+inline INTEGER_IMPL(I)::IntegerImpl( short n ) :
+ value_( static_cast<long>( n ) )
+{
+}
+
+TEMPLATE_DECL(I)
+inline INTEGER_IMPL(I)::IntegerImpl( int n ) :
+ value_( static_cast<long>( n ) )
+{
+}
+
+TEMPLATE_DECL(I)
+inline INTEGER_IMPL(I)::IntegerImpl( long n ) :
+ value_( n )
+{
+}
+
+#ifndef ZORBA_WITH_BIG_INTEGER
+TEMPLATE_DECL(I)
+inline INTEGER_IMPL(I)::IntegerImpl( long long n ) :
+ value_( n )
+{
+}
+#endif /* ZORBA_WITH_BIG_INTEGER */
+
+TEMPLATE_DECL(I)
+inline INTEGER_IMPL(I)::IntegerImpl( unsigned char c ) :
+ value_( static_cast<long>( c ) )
+{
+}
+
+TEMPLATE_DECL(I)
+inline INTEGER_IMPL(I)::IntegerImpl( unsigned short n ) :
+ value_( static_cast<long>( n ) )
+{
+}
+
+TEMPLATE_DECL(I)
+inline INTEGER_IMPL(I)::IntegerImpl( unsigned int n ) :
+ value_( static_cast<long>( n ) )
+{
+}
+
+#ifndef ZORBA_WITH_BIG_INTEGER
+TEMPLATE_DECL(I)
+inline INTEGER_IMPL(I)::IntegerImpl( unsigned long n ) :
+ value_( static_cast<value_type>( n ) )
+{
+}
+
+TEMPLATE_DECL(I)
+inline INTEGER_IMPL(I)::IntegerImpl( unsigned long long n ) :
+ value_( static_cast<value_type>( n ) )
+{
+}
+#endif /* ZORBA_WITH_BIG_INTEGER */
+
+TEMPLATE_DECL(I)
+inline INTEGER_IMPL(I)::IntegerImpl( float n ) :
#ifdef ZORBA_WITH_BIG_INTEGER
value_( static_cast<double>( n ) )
#else
@@ -336,8 +421,8 @@
{
}
-TEMPLATE_DECL(T)
-inline INTEGER_IMPL(T)::IntegerImpl( double n ) :
+TEMPLATE_DECL(I)
+inline INTEGER_IMPL(I)::IntegerImpl( double n ) :
#ifdef ZORBA_WITH_BIG_INTEGER
value_( n )
#else
@@ -346,111 +431,56 @@
{
}
-TEMPLATE_DECL(T)
-inline INTEGER_IMPL(T)::IntegerImpl( char const *s ) {
+TEMPLATE_DECL(I)
+inline INTEGER_IMPL(I)::IntegerImpl( char const *s ) {
parse( s );
}
-TEMPLATE_DECL(T)
-TEMPLATE_DECL(U)
-inline INTEGER_IMPL(T)::IntegerImpl( INTEGER_IMPL(U) const &i ) :
+TEMPLATE_DECL(I)
+TEMPLATE_DECL(J)
+inline INTEGER_IMPL(I)::IntegerImpl( INTEGER_IMPL(J) const &i ) :
value_( i.value_ )
{
}
////////// assignment operators ///////////////////////////////////////////////
-TEMPLATE_DECL(T)
-inline INTEGER_IMPL(T)& INTEGER_IMPL(T)::operator=( char c ) {
- value_ = static_cast<long>( c );
- return *this;
-}
-
-TEMPLATE_DECL(T)
-inline INTEGER_IMPL(T)& INTEGER_IMPL(T)::operator=( signed char c ) {
- value_ = static_cast<long>( c );
- return *this;
-}
-
-TEMPLATE_DECL(T)
-inline INTEGER_IMPL(T)& INTEGER_IMPL(T)::operator=( short n ) {
- value_ = static_cast<long>( n );
- return *this;
-}
-
-TEMPLATE_DECL(T)
-inline INTEGER_IMPL(T)& INTEGER_IMPL(T)::operator=( int n ) {
- value_ = static_cast<long>( n );
- return *this;
-}
-
-TEMPLATE_DECL(T)
-inline INTEGER_IMPL(T)& INTEGER_IMPL(T)::operator=( long n ) {
- value_ = n;
- return *this;
-}
-
-#ifndef ZORBA_WITH_BIG_INTEGER
-TEMPLATE_DECL(T)
-inline INTEGER_IMPL(T)& INTEGER_IMPL(T)::operator=( long long n ) {
- value_ = n;
- return *this;
-}
-#endif /* ZORBA_WITH_BIG_INTEGER */
-
-TEMPLATE_DECL(T)
-inline INTEGER_IMPL(T)& INTEGER_IMPL(T)::operator=( unsigned char c ) {
- value_ = static_cast<long>( c );
- return *this;
-}
-
-TEMPLATE_DECL(T)
-inline INTEGER_IMPL(T)& INTEGER_IMPL(T)::operator=( unsigned short n ) {
- value_ = static_cast<long>( n );
- return *this;
-}
-
-TEMPLATE_DECL(T)
-inline INTEGER_IMPL(T)& INTEGER_IMPL(T)::operator=( unsigned int n ) {
- value_ = static_cast<long>( n );
- return *this;
-}
-
-#ifndef ZORBA_WITH_BIG_INTEGER
-TEMPLATE_DECL(T)
-inline INTEGER_IMPL(T)& INTEGER_IMPL(T)::operator=( unsigned long n ) {
- value_ = static_cast<long>( n );
- return *this;
-}
-
-TEMPLATE_DECL(T)
-inline INTEGER_IMPL(T)& INTEGER_IMPL(T)::operator=( unsigned long long n ) {
- value_ = n;
- return *this;
-}
-#endif /* ZORBA_WITH_BIG_INTEGER */
-
-TEMPLATE_DECL(T)
-inline INTEGER_IMPL(T)& INTEGER_IMPL(T)::operator=( float n ) {
- value_ = static_cast<long>( n );
- return *this;
-}
-
-TEMPLATE_DECL(T)
-inline INTEGER_IMPL(T)& INTEGER_IMPL(T)::operator=( double n ) {
- value_ = static_cast<long>( n );
- return *this;
-}
-
-TEMPLATE_DECL(T)
-inline INTEGER_IMPL(T)& INTEGER_IMPL(T)::operator=( char const *s ) {
+TEMPLATE_DECL(I) template<typename A> inline
+typename std::enable_if<ZORBA_TR1_NS::is_arithmetic<A>::value,
+ INTEGER_IMPL(I)&>::type
+INTEGER_IMPL(I)::operator=( A n ) {
+ value_ = static_cast<long>( n );
+ return *this;
+}
+
+#ifndef ZORBA_WITH_BIG_INTEGER
+template<typename I>
+inline IntegerImpl<I>& IntegerImpl<I>::operator=( long long n ) {
+ value_ = n;
+ return *this;
+}
+
+template<typename I>
+inline IntegerImpl<I>& IntegerImpl<I>::operator=( unsigned long n ) {
+ value_ = static_cast<long>( n );
+ return *this;
+}
+
+template<typename I>
+inline IntegerImpl<I>& IntegerImpl<I>::operator=( unsigned long long n ) {
+ value_ = n;
+ return *this;
+}
+#endif /* ZORBA_WITH_BIG_INTEGER */
+
+TEMPLATE_DECL(I)
+inline INTEGER_IMPL(I)& INTEGER_IMPL(I)::operator=( char const *s ) {
parse( s );
return *this;
}
-TEMPLATE_DECL(T)
-TEMPLATE_DECL(U)
-inline INTEGER_IMPL(T)& INTEGER_IMPL(T)::operator=( INTEGER_IMPL(U) const &i ) {
+TEMPLATE_DECL(I) TEMPLATE_DECL(J)
+inline INTEGER_IMPL(I)& INTEGER_IMPL(I)::operator=( INTEGER_IMPL(J) const &i ) {
value_ = i.value_;
return *this;
}
@@ -458,26 +488,66 @@
////////// arithmetic operators ///////////////////////////////////////////////
#define ZORBA_INTEGER_OP(OP) \
- TEMPLATE_DECL(T) inline \
- INTEGER_IMPL(T) operator OP( INTEGER_IMPL(T) const &i, \
- INTEGER_IMPL(T) const &j ) { \
- return i.value_ OP j.value_; \
- }
-
-ZORBA_INTEGER_OP(+)
-ZORBA_INTEGER_OP(-)
-ZORBA_INTEGER_OP(*)
-ZORBA_INTEGER_OP(%)
-#undef ZORBA_INTEGER_OP
-
-TEMPLATE_DECL(T) inline
-INTEGER_IMPL(T) operator/( INTEGER_IMPL(T) const &i, INTEGER_IMPL(T) const &j ) {
- return INTEGER_IMPL(T)::ftoi( i.value_ / j.value_ );
+ TEMPLATE_DECL(I) inline \
+ INTEGER_IMPL(I) operator OP( INTEGER_IMPL(I) const &i, \
+ INTEGER_IMPL(I) const &j ) { \
+ return INTEGER_IMPL(I)( i.value_ OP j.value_ ); \
+ }
+
+ZORBA_INTEGER_OP(+)
+ZORBA_INTEGER_OP(-)
+ZORBA_INTEGER_OP(*)
+ZORBA_INTEGER_OP(%)
+#undef ZORBA_INTEGER_OP
+
+TEMPLATE_DECL(I) inline
+INTEGER_IMPL(I) operator/( INTEGER_IMPL(I) const &i,
+ INTEGER_IMPL(I) const &j ) {
+ return INTEGER_IMPL(I)( INTEGER_IMPL(I)::ftoi( i.value_ / j.value_ ) );
+}
+
+#define ZORBA_INTEGER_OP(OP) \
+ TEMPLATE_DECL2(I,A) inline \
+ typename std::enable_if<ZORBA_TR1_NS::is_arithmetic<A>::value, \
+ INTEGER_IMPL(I)>::type \
+ operator OP( INTEGER_IMPL(I) const& i, A n ) { \
+ return INTEGER_IMPL(I)( i.value_ OP INTEGER_IMPL(I)::cast( n ) ); \
+ } \
+ \
+ TEMPLATE_DECL2(I,A) inline \
+ typename std::enable_if<ZORBA_TR1_NS::is_arithmetic<A>::value, \
+ INTEGER_IMPL(I)>::type \
+ operator OP( A n, INTEGER_IMPL(I) const &i ) { \
+ return INTEGER_IMPL(I)( INTEGER_IMPL(I)::cast( n ) OP i.value_ ); \
+ }
+
+ZORBA_INTEGER_OP(+)
+ZORBA_INTEGER_OP(-)
+ZORBA_INTEGER_OP(*)
+ZORBA_INTEGER_OP(%)
+#undef ZORBA_INTEGER_OP
+
+TEMPLATE_DECL2(I,A) inline
+typename std::enable_if<ZORBA_TR1_NS::is_arithmetic<A>::value,
+ INTEGER_IMPL(I)>::type
+operator/( INTEGER_IMPL(I) const &i, A n ) {
+ return INTEGER_IMPL(I)(
+ INTEGER_IMPL(I)::ftoi( i.value_ / INTEGER_IMPL(I)::cast( n ) )
+ );
+}
+
+TEMPLATE_DECL2(I,A) inline
+typename std::enable_if<ZORBA_TR1_NS::is_arithmetic<A>::value,
+ INTEGER_IMPL(I)>::type
+operator/( A n, INTEGER_IMPL(I) const &i ) {
+ return INTEGER_IMPL(I)(
+ INTEGER_IMPL(I)::ftoi( INTEGER_IMPL(I)::cast( n ) / i.value_ )
+ );
}
#define ZORBA_INTEGER_OP(OP) \
- TEMPLATE_DECL(T) inline \
- INTEGER_IMPL(T)& INTEGER_IMPL(T)::operator OP( IntegerImpl const &i ) { \
+ TEMPLATE_DECL(I) inline \
+ INTEGER_IMPL(I)& INTEGER_IMPL(I)::operator OP( IntegerImpl const &i ) { \
value_ OP i.value_; \
return *this; \
}
@@ -488,39 +558,62 @@
ZORBA_INTEGER_OP(%=)
#undef ZORBA_INTEGER_OP
-TEMPLATE_DECL(T)
-inline INTEGER_IMPL(T)& INTEGER_IMPL(T)::operator/=( IntegerImpl const &i ) {
+TEMPLATE_DECL(I)
+inline INTEGER_IMPL(I)& INTEGER_IMPL(I)::operator/=( IntegerImpl const &i ) {
value_ = ftoi( value_ / i.value_ );
return *this;
}
-TEMPLATE_DECL(T)
-inline INTEGER_IMPL(T) INTEGER_IMPL(T)::operator-() const {
- return -value_;
-}
-
-TEMPLATE_DECL(T)
-inline INTEGER_IMPL(T)& INTEGER_IMPL(T)::operator++() {
+#define ZORBA_INTEGER_OP(OP) \
+ TEMPLATE_DECL(I) template<typename A> inline \
+ typename std::enable_if<ZORBA_TR1_NS::is_arithmetic<A>::value, \
+ INTEGER_IMPL(I)&>::type \
+ INTEGER_IMPL(I)::operator OP( A n ) { \
+ value_ OP cast( n ); \
+ return *this; \
+ }
+
+ZORBA_INTEGER_OP(+=)
+ZORBA_INTEGER_OP(-=)
+ZORBA_INTEGER_OP(*=)
+ZORBA_INTEGER_OP(%=)
+#undef ZORBA_INTEGER_OP
+
+TEMPLATE_DECL(I) template<typename A> inline
+typename std::enable_if<ZORBA_TR1_NS::is_arithmetic<A>::value,
+ INTEGER_IMPL(I)&>::type
+INTEGER_IMPL(I)::operator/=( A n ) {
+ value_ = ftoi( value_ / cast( n ) );
+ return *this;
+}
+
+TEMPLATE_DECL(I)
+inline INTEGER_IMPL(I) INTEGER_IMPL(I)::operator-() const {
+ return INTEGER_IMPL(I)( -value_ );
+}
+
+TEMPLATE_DECL(I)
+inline INTEGER_IMPL(I)& INTEGER_IMPL(I)::operator++() {
++value_;
return *this;
}
-TEMPLATE_DECL(T)
-inline INTEGER_IMPL(T) INTEGER_IMPL(T)::operator++(int) {
- INTEGER_IMPL(T) const result( *this );
+TEMPLATE_DECL(I)
+inline INTEGER_IMPL(I) INTEGER_IMPL(I)::operator++(int) {
+ INTEGER_IMPL(I) const result( *this );
++value_;
return result;
}
-TEMPLATE_DECL(T)
-inline INTEGER_IMPL(T)& INTEGER_IMPL(T)::operator--() {
+TEMPLATE_DECL(I)
+inline INTEGER_IMPL(I)& INTEGER_IMPL(I)::operator--() {
--value_;
return *this;
}
-TEMPLATE_DECL(T)
-inline INTEGER_IMPL(T) INTEGER_IMPL(T)::operator--(int) {
- INTEGER_IMPL(T) const result( *this );
+TEMPLATE_DECL(I)
+inline INTEGER_IMPL(I) INTEGER_IMPL(I)::operator--(int) {
+ INTEGER_IMPL(I) const result( *this );
--value_;
return result;
}
@@ -528,8 +621,8 @@
////////// relational operators ///////////////////////////////////////////////
#define ZORBA_INTEGER_OP(OP) \
- TEMPLATE_DECL(T) inline \
- bool operator OP( INTEGER_IMPL(T) const &i, INTEGER_IMPL(T) const &j ) { \
+ TEMPLATE_DECL(I) inline \
+ bool operator OP( INTEGER_IMPL(I) const &i, INTEGER_IMPL(I) const &j ) { \
return i.value_ OP j.value_; \
}
@@ -541,6 +634,27 @@
ZORBA_INTEGER_OP(>=)
#undef ZORBA_INTEGER_OP
+#define ZORBA_INTEGER_OP(OP) \
+ TEMPLATE_DECL2(I,A) inline \
+ typename std::enable_if<ZORBA_TR1_NS::is_arithmetic<A>::value,bool>::type \
+ operator OP( INTEGER_IMPL(I) const &i, A n ) { \
+ return i.value_ OP INTEGER_IMPL(I)::cast( n ); \
+ } \
+ \
+ TEMPLATE_DECL2(I,A) inline \
+ typename std::enable_if<ZORBA_TR1_NS::is_arithmetic<A>::value,bool>::type \
+ operator OP( A n, INTEGER_IMPL(I) const &i ) { \
+ return INTEGER_IMPL(I)::cast( n ) OP i.value_; \
+ } \
+
+ ZORBA_INTEGER_OP(==)
+ ZORBA_INTEGER_OP(!=)
+ ZORBA_INTEGER_OP(< )
+ ZORBA_INTEGER_OP(<=)
+ ZORBA_INTEGER_OP(> )
+ ZORBA_INTEGER_OP(>=)
+#undef ZORBA_INTEGER_OP
+
////////// miscellaneous //////////////////////////////////////////////////////
#ifdef ZORBA_WITH_BIG_INTEGER
@@ -555,31 +669,31 @@
#else
-template<typename IntType>
-inline int IntegerImpl<IntType>::compare( IntegerImpl const &i ) const {
+template<typename I>
+inline int IntegerImpl<I>::compare( IntegerImpl const &i ) const {
return value_ < i.value_ ? -1 : value_ > i.value_ ? 1 : 0;
}
-template<typename IntType>
-inline uint32_t IntegerImpl<IntType>::hash() const {
+template<typename I>
+inline uint32_t IntegerImpl<I>::hash() const {
return static_cast<uint32_t>( value_ );
}
-template<typename IntType>
-inline bool IntegerImpl<IntType>::is_long() const {
+template<typename I>
+inline bool IntegerImpl<I>::is_long() const {
return value_ >= std::numeric_limits<long>::min() &&
value_ <= std::numeric_limits<long>::max();
}
-template<typename IntType>
-inline int IntegerImpl<IntType>::sign() const {
+template<typename I>
+inline int IntegerImpl<I>::sign() const {
return ztd::lt0( value_ ) ? -1 : value_ > 0 ? 1 : 0;
}
#endif /* ZORBA_WITH_BIG_INTEGER */
-TEMPLATE_DECL(T)
-inline std::ostream& operator<<( std::ostream &os, INTEGER_IMPL(T) const &i ) {
+TEMPLATE_DECL(I)
+inline std::ostream& operator<<( std::ostream &os, INTEGER_IMPL(I) const &i ) {
return os << i.toString();
}
Follow ups