diff --git a/apps/sequence/sequence.cpp b/apps/sequence/sequence.cpp index c463a007e..f29a4b0ce 100644 --- a/apps/sequence/sequence.cpp +++ b/apps/sequence/sequence.cpp @@ -89,9 +89,9 @@ bool Sequence::isDefined() { case Type::Explicit: return Function::isDefined(); case Type::SingleRecurrence: - return Function::isDefined() && data->firstInitialConditionSize() > 0; + return Function::isDefined() && data->initialConditionSize(0) > 0; default: - return Function::isDefined() && data->firstInitialConditionSize() > 0 && data->secondInitialConditionSize() > 0; + return Function::isDefined() && data->initialConditionSize(0) > 0 && data->initialConditionSize(1) > 0; } } @@ -101,9 +101,9 @@ bool Sequence::isEmpty() { case Type::Explicit: return Function::isEmpty(); case Type::SingleRecurrence: - return Function::isEmpty() && data->firstInitialConditionSize() == 0; + return Function::isEmpty() && data->initialConditionSize(0) == 0; default: - return Function::isEmpty() && data->firstInitialConditionSize() == 0 && data->secondInitialConditionSize() == 0; + return Function::isEmpty() && data->initialConditionSize(0) == 0 && data->initialConditionSize(1) == 0; } } @@ -191,7 +191,7 @@ Sequence::SequenceRecordDataBuffer * Sequence::recordData() const { return reinterpret_cast(const_cast(d.buffer)); } -/* Sequence Handle */ +/* Sequence Model */ Poincare::Layout Sequence::SequenceModel::name(Sequence * sequence) { if (m_name.isUninitialized()) { @@ -223,7 +223,7 @@ void * Sequence::DefinitionModel::expressionAddress(const Ion::Storage::Record * size_t Sequence::DefinitionModel::expressionSize(const Ion::Storage::Record * record) const { Ion::Storage::Record::Data data = record->value(); SequenceRecordDataBuffer * dataBuffer = static_cast(record)->recordData(); - return data.size-sizeof(SequenceRecordDataBuffer) - dataBuffer->firstInitialConditionSize() - dataBuffer->secondInitialConditionSize(); + return data.size-sizeof(SequenceRecordDataBuffer) - dataBuffer->initialConditionSize(0) - dataBuffer->initialConditionSize(1); } void Sequence::DefinitionModel::buildName(Sequence * sequence) { @@ -244,54 +244,27 @@ void Sequence::DefinitionModel::buildName(Sequence * sequence) { } } -/* First Initial Condition Handle*/ +/* Initial Condition Handle*/ -void * Sequence::FirstInitialConditionModel::expressionAddress(const Ion::Storage::Record * record) const { +void * Sequence::InitialConditionModel::expressionAddress(const Ion::Storage::Record * record) const { Ion::Storage::Record::Data data = record->value(); SequenceRecordDataBuffer * dataBuffer = static_cast(record)->recordData(); - size_t offset = data.size - dataBuffer->firstInitialConditionSize() - dataBuffer->secondInitialConditionSize(); + size_t offset = conditionIndex() == 0 ? data.size - dataBuffer->initialConditionSize(0) - dataBuffer->initialConditionSize(1) : data.size - dataBuffer->initialConditionSize(1) ; return (char *)data.buffer+offset; } -size_t Sequence::FirstInitialConditionModel::expressionSize(const Ion::Storage::Record * record) const { - return static_cast(record)->recordData()->firstInitialConditionSize(); +size_t Sequence::InitialConditionModel::expressionSize(const Ion::Storage::Record * record) const { + return static_cast(record)->recordData()->initialConditionSize(conditionIndex()); } -void Sequence::FirstInitialConditionModel::updateMetaData(const Ion::Storage::Record * record, size_t newSize) { - static_cast(record)->recordData()->setFirstInitialConditionSize(newSize); +void Sequence::InitialConditionModel::updateMetaData(const Ion::Storage::Record * record, size_t newSize) { + static_cast(record)->recordData()->setInitialConditionSize(newSize, conditionIndex()); } -void Sequence::FirstInitialConditionModel::buildName(Sequence * sequence) { - assert(sequence->type() == Type::SingleRecurrence || sequence->type() == Type::DoubleRecurrence); +void Sequence::InitialConditionModel::buildName(Sequence * sequence) { + assert((conditionIndex() == 0 && sequence->type() == Type::SingleRecurrence) || sequence->type() == Type::DoubleRecurrence); char buffer[k_initialRankNumberOfDigits+1]; - Integer(sequence->initialRank()).serialize(buffer, k_initialRankNumberOfDigits+1); - Layout indexLayout = LayoutHelper::String(buffer, strlen(buffer), k_layoutFont); - m_name = HorizontalLayout::Builder( - CodePointLayout::Builder(sequence->fullName()[0], k_layoutFont), - VerticalOffsetLayout::Builder(indexLayout, VerticalOffsetLayoutNode::Type::Subscript)); -} - -/* Second Initial Condition Handle*/ - -void * Sequence::SecondInitialConditionModel::expressionAddress(const Ion::Storage::Record * record) const { - Ion::Storage::Record::Data data = record->value(); - SequenceRecordDataBuffer * dataBuffer = static_cast(record)->recordData(); - size_t offset = data.size - dataBuffer->secondInitialConditionSize(); - return (char *)data.buffer+offset; -} - -void Sequence::SecondInitialConditionModel::updateMetaData(const Ion::Storage::Record * record, size_t newSize) { - static_cast(record)->recordData()->setSecondInitialConditionSize(newSize); -} - -size_t Sequence::SecondInitialConditionModel::expressionSize(const Ion::Storage::Record * record) const { - return static_cast(record)->recordData()->secondInitialConditionSize(); -} - -void Sequence::SecondInitialConditionModel::buildName(Sequence * sequence) { - assert(sequence->type() == Type::DoubleRecurrence); - char buffer[k_initialRankNumberOfDigits+1]; - Integer(sequence->initialRank()+1).serialize(buffer, k_initialRankNumberOfDigits+1); + Integer(sequence->initialRank()+conditionIndex()).serialize(buffer, k_initialRankNumberOfDigits+1); Layout indexLayout = LayoutHelper::String(buffer, strlen(buffer), k_layoutFont); m_name = HorizontalLayout::Builder( CodePointLayout::Builder(sequence->fullName()[0], k_layoutFont), diff --git a/apps/sequence/sequence.h b/apps/sequence/sequence.h index 91c7d19e9..61e43386e 100644 --- a/apps/sequence/sequence.h +++ b/apps/sequence/sequence.h @@ -77,23 +77,26 @@ private: FunctionRecordDataBuffer(color), m_type(Type::Explicit), m_initialRank(0), - m_firstInitialConditionSize(0), - m_secondInitialConditionSize(0) + m_initialConditionSizes{0,0} {} Type type() const { return m_type; } void setType(Type type) { m_type = type; } int initialRank() const { return m_initialRank; } void setInitialRank(int initialRank) { m_initialRank = initialRank; } - size_t firstInitialConditionSize() const { return m_firstInitialConditionSize; } - void setFirstInitialConditionSize(uint16_t firstInitialConditionSize) { m_firstInitialConditionSize = firstInitialConditionSize; } - size_t secondInitialConditionSize() const { return m_secondInitialConditionSize; } - void setSecondInitialConditionSize(uint16_t secondInitialConditionSize) { m_secondInitialConditionSize = secondInitialConditionSize; } + size_t initialConditionSize(int conditionIndex) { + assert(conditionIndex >= 0 && conditionIndex < 2); + return m_initialConditionSizes[conditionIndex]; + } + void setInitialConditionSize(uint16_t size, int conditionIndex) { + assert(conditionIndex >= 0 && conditionIndex < 2); + m_initialConditionSizes[conditionIndex] = size; + } + private: static_assert((1 << 8*sizeof(uint16_t)) > Ion::Storage::k_storageSize, "Potential overflows of Sequence initial condition sizes"); Type m_type; uint8_t m_initialRank; - uint16_t m_firstInitialConditionSize; - uint16_t m_secondInitialConditionSize; + uint16_t m_initialConditionSizes[2]; }; class SequenceModel : public Shared::ExpressionModel { @@ -117,22 +120,24 @@ private: void buildName(Sequence * sequence) override; }; - class FirstInitialConditionModel : public SequenceModel { + class InitialConditionModel : public SequenceModel { public: void * expressionAddress(const Ion::Storage::Record * record) const override; private: void updateMetaData(const Ion::Storage::Record * record, size_t newSize) override; size_t expressionSize(const Ion::Storage::Record * record) const override; void buildName(Sequence * sequence) override; + virtual int conditionIndex() const = 0; }; - class SecondInitialConditionModel : public SequenceModel { - public: - void * expressionAddress(const Ion::Storage::Record * record) const override; + class FirstInitialConditionModel : public InitialConditionModel { private: - void updateMetaData(const Ion::Storage::Record * record, size_t newSize) override; - size_t expressionSize(const Ion::Storage::Record * record) const override; - void buildName(Sequence * sequence) override; + int conditionIndex() const override { return 0; } + }; + + class SecondInitialConditionModel : public InitialConditionModel { + private: + int conditionIndex() const override { return 1; } }; template T templatedApproximateAtAbscissa(T x, SequenceContext * sqctx) const;