<commit_before>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2012.  All rights reserved
 */
#ifndef _Stroika_Foundation_Containers_Concrete_Bag_Array_inl_
#define _Stroika_Foundation_Containers_Concrete_Bag_Array_inl_

#include    "../../Memory/BlockAllocated.h"

#include    "Private/Array.h"

namespace   Stroika {
    namespace   Foundation {
        namespace   Containers {
            namespace   Concrete {

                template    <typename T>
                class   Bag_Array<T>::Rep_ : public Bag<T>::_IRep {
                public:
                    Rep_ ();
                    ~Rep_ ();

                public:
                    DECLARE_USE_BLOCK_ALLOCATION (Rep_);

                    // Iterable<T>::_IRep overrides
                public:
                    virtual typename Iterable<T>::_IRep*    Clone () const override;
                    virtual Iterator<T>                     MakeIterator () const override;
                    virtual size_t                          GetLength () const override;
                    virtual bool                            IsEmpty () const override;
                    virtual void                            Apply (void (*doToElement) (const T& item)) const override;
                    virtual Iterator<T>                     ApplyUntilTrue (bool (*doToElement) (const T& item)) const override;

                    // Bag<T>::_IRep overrides
                public:
                    virtual void                        Compact () override;
                    virtual bool                        Contains (T item) const override;
                    virtual typename Bag<T>::Mutator    MakeMutator () override;
                    virtual void                        Add (T item) override;
                    virtual void                        Remove (T item) override;
                    virtual void                        RemoveAll () override;

                private:
                    Array_Patch<T>  fData_;
                    friend  class Bag_Array<T>::MutatorRep_;
                };

                template    <typename T>
                class  Bag_Array<T>::MutatorRep_ : public Bag<T>::_IMutatorRep {
                public:
                    MutatorRep_ (typename Bag_Array<T>::Rep_& owner);

                public:
                    DECLARE_USE_BLOCK_ALLOCATION (MutatorRep_);

                public:
                    virtual bool    More (T* current, bool advance) override;
                    virtual T       Current () const override;

                    virtual typename Iterator<T>::Rep*      Clone () const override;

                    virtual void    RemoveCurrent () override;
                    virtual void    UpdateCurrent (T newValue) override;

                private:
                    ForwardArrayMutator_Patch<T>    fIterator_;
                    friend  class   Rep_;
                };

                //  class   Bag_Array<T>::MutatorRep_<T>
                template    <class  T>
                Bag_Array<T>::MutatorRep_::MutatorRep_ (typename Bag_Array<T>::Rep_& owner)
                    : Bag<T>::_IMutatorRep ()
                    , fIterator_ (owner.fData_)
                {
                }
                template    <class  T>
                bool    Bag_Array<T>::MutatorRep_::More (T* current, bool advance)
                {
                    return (fIterator_.More (current, advance));
                }
                template    <class  T>
                T   Bag_Array<T>::MutatorRep_::Current () const
                {
                    return (fIterator_.Current());
                }
                template    <typename T>
                typename Iterator<T>::Rep*  Bag_Array<T>::MutatorRep_::Clone () const
                {
                    return (new MutatorRep_ (*this));
                }
                template    <class  T>
                void    Bag_Array<T>::MutatorRep_::RemoveCurrent ()
                {
                    fIterator_.RemoveCurrent ();
                }
                template    <class  T>
                void    Bag_Array<T>::MutatorRep_::UpdateCurrent (T newValue)
                {
                    fIterator_.UpdateCurrent (newValue);
                }

                //  class   Bag_Array<T>::Rep_
                template    <typename T>
                inline  Bag_Array<T>::Rep_::Rep_ () :
                    fData_ ()
                {
                }
                template    <typename T>
                Bag_Array<T>::Rep_::~Rep_ ()
                {
                }
                template    <typename T>
                typename Iterable<T>::_IRep*  Bag_Array<T>::Rep_::Clone () const
                {
                    return (new Rep_ (*this));
                }
                template    <typename T>
                Iterator<T>  Bag_Array<T>::Rep_::MakeIterator () const
                {
                    Rep_*   NON_CONST_THIS  =   const_cast<Rep_*> (this);       // logically const, but non-const cast cuz re-using iterator API
                    return Iterator<T> (new MutatorRep_ (*NON_CONST_THIS));
                }
                template    <typename T>
                size_t  Bag_Array<T>::Rep_::GetLength () const
                {
                    return (fData_.GetLength ());
                }
                template    <typename T>
                bool  Bag_Array<T>::Rep_::IsEmpty () const
                {
                    return (fData_.GetLength () == 0);
                }
                template    <typename T>
                void      Bag_Array<T>::Rep_::Apply (void (*doToElement) (const T& item)) const override
                {
                    return _Apply (doToElement);
                }
                template    <typename T>
                Iterator<T>     Bag_Array<T>::Rep_::ApplyUntilTrue (bool (*doToElement) (const T& item)) const override
                {
                    return _ApplyUntilTrue (doToElement);
                }
                template    <typename T>
                void    Bag_Array<T>::Rep_::Compact ()
                {
                    fData_.Compact ();
                }
                template    <typename T>
                bool    Bag_Array<T>::Rep_::Contains (T item) const
                {
                    return (fData_.Contains (item));
                }
                template    <typename T>
                typename    typename Bag<T>::Mutator   Bag_Array<T>::Rep_::MakeMutator ()
                {
                    return typename Bag<T>::Mutator (new MutatorRep_ (*this));
                }
                template    <typename T>
                void    Bag_Array<T>::Rep_::Add (T item)
                {
                    // Appending is fastest
                    fData_.InsertAt (item, GetLength ());
                }
                template    <typename T>
                void    Bag_Array<T>::Rep_::Remove (T item)
                {
                    /*
                     *      Iterate backwards since removing from the end of an array
                     *  will be faster.
                     */
                    for (BackwardArrayIterator<T> it (fData_); it.More (nullptr, true);) {
                        if (it.Current () == item) {
                            fData_.RemoveAt (it.CurrentIndex ());
                            return;
                        }
                    }
                }
                template    <typename T>
                void    Bag_Array<T>::Rep_::RemoveAll ()
                {
                    fData_.RemoveAll ();
                }

                //  class   Bag_Array<T>
                template    <typename T>    Bag_Array<T>::Bag_Array ()
                    : Bag<T> (new Rep_ ())
                {
                }
                template    <typename T>    Bag_Array<T>::Bag_Array (const Bag<T>& bag)
                    : Bag<T> (new Rep_ ())
                {
                    SetCapacity (bag.GetLength ());
                    operator+= (bag);
                }
                template    <typename T>    Bag_Array<T>::Bag_Array (const T* start, const T* end)
                    : Bag<T> (new Rep_ ())
                {
                    Require ((start == end) or (start != nullptr and end != nullptr));
                    if (start != end) {
                        SetCapacity (end - start);
                        Add (start, end);
                    }
                }
                template    <typename T>
                inline  Bag_Array<T>::Bag_Array (const Bag_Array<T>& bag) :
                    Bag<T> (bag)
                {
                }
                template    <typename T>
                inline  Bag_Array<T>&   Bag_Array<T>::operator= (const Bag_Array<T>& bag)
                {
                    Bag<T>::operator= (bag);
                    return (*this);
                }
                template    <typename T>
                inline  const typename Bag_Array<T>::Rep_&  Bag_Array<T>::GetRep_ () const
                {
                    /*
                     * This cast is safe since we are very careful to assure we always have a pointer
                     * to this type. We could keep extra pointer, but that would cost space and time,
                     * and with care we don't need to.
                     */
                    return (static_cast<const Rep_&> (Bag<T>::_GetRep ()));
                }
                template    <typename T>
                inline  typename Bag_Array<T>::Rep_&    Bag_Array<T>::GetRep_ ()
                {
                    /*
                     * This cast is safe since we are very careful to assure we always have a pointer
                     * to this type. We could keep extra pointer, but that would cost space and time,
                     * and with care we don't need to.
                     */
                    return (static_cast<const Rep_&> (Bag<T>::_GetRep ()));
                }
                template    <typename T>
                inline  size_t  Bag_Array<T>::GetCapacity () const
                {
                    return (GetRep_ ().fData_.GetCapacity ());
                }
                template    <typename T>
                inline  void    Bag_Array<T>::SetCapacity (size_t slotsAlloced)
                {
                    GetRep_ ().fData_.SetCapacity (slotsAlloced);
                }

            }
        }
    }
}

#endif /* _Stroika_Foundation_Containers_Concrete_Bag_Array_inl_ */
<commit_msg>fixed small gcc-only bug with bag<T> code<commit_after>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2012.  All rights reserved
 */
#ifndef _Stroika_Foundation_Containers_Concrete_Bag_Array_inl_
#define _Stroika_Foundation_Containers_Concrete_Bag_Array_inl_

#include    "../../Memory/BlockAllocated.h"

#include    "Private/Array.h"

namespace   Stroika {
    namespace   Foundation {
        namespace   Containers {
            namespace   Concrete {

                template    <typename T>
                class   Bag_Array<T>::Rep_ : public Bag<T>::_IRep {
                public:
                    Rep_ ();
                    ~Rep_ ();

                public:
                    DECLARE_USE_BLOCK_ALLOCATION (Rep_);

                    // Iterable<T>::_IRep overrides
                public:
                    virtual typename Iterable<T>::_IRep*    Clone () const override;
                    virtual Iterator<T>                     MakeIterator () const override;
                    virtual size_t                          GetLength () const override;
                    virtual bool                            IsEmpty () const override;
                    virtual void                            Apply (void (*doToElement) (const T& item)) const override;
                    virtual Iterator<T>                     ApplyUntilTrue (bool (*doToElement) (const T& item)) const override;

                    // Bag<T>::_IRep overrides
                public:
                    virtual void                        Compact () override;
                    virtual bool                        Contains (T item) const override;
                    virtual typename Bag<T>::Mutator    MakeMutator () override;
                    virtual void                        Add (T item) override;
                    virtual void                        Remove (T item) override;
                    virtual void                        RemoveAll () override;

                private:
                    Array_Patch<T>  fData_;
                    friend  class Bag_Array<T>::MutatorRep_;
                };

                template    <typename T>
                class  Bag_Array<T>::MutatorRep_ : public Bag<T>::_IMutatorRep {
                public:
                    MutatorRep_ (typename Bag_Array<T>::Rep_& owner);

                public:
                    DECLARE_USE_BLOCK_ALLOCATION (MutatorRep_);

                public:
                    virtual bool    More (T* current, bool advance) override;
                    virtual T       Current () const override;

                    virtual typename Iterator<T>::Rep*      Clone () const override;

                    virtual void    RemoveCurrent () override;
                    virtual void    UpdateCurrent (T newValue) override;

                private:
                    ForwardArrayMutator_Patch<T>    fIterator_;
                    friend  class   Rep_;
                };

                //  class   Bag_Array<T>::MutatorRep_<T>
                template    <class  T>
                Bag_Array<T>::MutatorRep_::MutatorRep_ (typename Bag_Array<T>::Rep_& owner)
                    : Bag<T>::_IMutatorRep ()
                    , fIterator_ (owner.fData_)
                {
                }
                template    <class  T>
                bool    Bag_Array<T>::MutatorRep_::More (T* current, bool advance)
                {
                    return (fIterator_.More (current, advance));
                }
                template    <class  T>
                T   Bag_Array<T>::MutatorRep_::Current () const
                {
                    return (fIterator_.Current());
                }
                template    <typename T>
                typename Iterator<T>::Rep*  Bag_Array<T>::MutatorRep_::Clone () const
                {
                    return (new MutatorRep_ (*this));
                }
                template    <class  T>
                void    Bag_Array<T>::MutatorRep_::RemoveCurrent ()
                {
                    fIterator_.RemoveCurrent ();
                }
                template    <class  T>
                void    Bag_Array<T>::MutatorRep_::UpdateCurrent (T newValue)
                {
                    fIterator_.UpdateCurrent (newValue);
                }

                //  class   Bag_Array<T>::Rep_
                template    <typename T>
                inline  Bag_Array<T>::Rep_::Rep_ () :
                    fData_ ()
                {
                }
                template    <typename T>
                Bag_Array<T>::Rep_::~Rep_ ()
                {
                }
                template    <typename T>
                typename Iterable<T>::_IRep*  Bag_Array<T>::Rep_::Clone () const
                {
                    return (new Rep_ (*this));
                }
                template    <typename T>
                Iterator<T>  Bag_Array<T>::Rep_::MakeIterator () const
                {
                    Rep_*   NON_CONST_THIS  =   const_cast<Rep_*> (this);       // logically const, but non-const cast cuz re-using iterator API
                    return Iterator<T> (new MutatorRep_ (*NON_CONST_THIS));
                }
                template    <typename T>
                size_t  Bag_Array<T>::Rep_::GetLength () const
                {
                    return (fData_.GetLength ());
                }
                template    <typename T>
                bool  Bag_Array<T>::Rep_::IsEmpty () const
                {
                    return (fData_.GetLength () == 0);
                }
                template    <typename T>
                void      Bag_Array<T>::Rep_::Apply (void (*doToElement) (const T& item)) const override
                {
                    return _Apply (doToElement);
                }
                template    <typename T>
                Iterator<T>     Bag_Array<T>::Rep_::ApplyUntilTrue (bool (*doToElement) (const T& item)) const override
                {
                    return _ApplyUntilTrue (doToElement);
                }
                template    <typename T>
                void    Bag_Array<T>::Rep_::Compact ()
                {
                    fData_.Compact ();
                }
                template    <typename T>
                bool    Bag_Array<T>::Rep_::Contains (T item) const
                {
                    return (fData_.Contains (item));
                }
                template    <typename T>
                typename Bag<T>::Mutator   Bag_Array<T>::Rep_::MakeMutator ()
                {
                    return typename Bag<T>::Mutator (new MutatorRep_ (*this));
                }
                template    <typename T>
                void    Bag_Array<T>::Rep_::Add (T item)
                {
                    // Appending is fastest
                    fData_.InsertAt (item, GetLength ());
                }
                template    <typename T>
                void    Bag_Array<T>::Rep_::Remove (T item)
                {
                    /*
                     *      Iterate backwards since removing from the end of an array
                     *  will be faster.
                     */
                    for (BackwardArrayIterator<T> it (fData_); it.More (nullptr, true);) {
                        if (it.Current () == item) {
                            fData_.RemoveAt (it.CurrentIndex ());
                            return;
                        }
                    }
                }
                template    <typename T>
                void    Bag_Array<T>::Rep_::RemoveAll ()
                {
                    fData_.RemoveAll ();
                }

                //  class   Bag_Array<T>
                template    <typename T>    Bag_Array<T>::Bag_Array ()
                    : Bag<T> (new Rep_ ())
                {
                }
                template    <typename T>    Bag_Array<T>::Bag_Array (const Bag<T>& bag)
                    : Bag<T> (new Rep_ ())
                {
                    SetCapacity (bag.GetLength ());
                    operator+= (bag);
                }
                template    <typename T>    Bag_Array<T>::Bag_Array (const T* start, const T* end)
                    : Bag<T> (new Rep_ ())
                {
                    Require ((start == end) or (start != nullptr and end != nullptr));
                    if (start != end) {
                        SetCapacity (end - start);
                        Add (start, end);
                    }
                }
                template    <typename T>
                inline  Bag_Array<T>::Bag_Array (const Bag_Array<T>& bag) :
                    Bag<T> (bag)
                {
                }
                template    <typename T>
                inline  Bag_Array<T>&   Bag_Array<T>::operator= (const Bag_Array<T>& bag)
                {
                    Bag<T>::operator= (bag);
                    return (*this);
                }
                template    <typename T>
                inline  const typename Bag_Array<T>::Rep_&  Bag_Array<T>::GetRep_ () const
                {
                    /*
                     * This cast is safe since we are very careful to assure we always have a pointer
                     * to this type. We could keep extra pointer, but that would cost space and time,
                     * and with care we don't need to.
                     */
                    return (static_cast<const Rep_&> (Bag<T>::_GetRep ()));
                }
                template    <typename T>
                inline  typename Bag_Array<T>::Rep_&    Bag_Array<T>::GetRep_ ()
                {
                    /*
                     * This cast is safe since we are very careful to assure we always have a pointer
                     * to this type. We could keep extra pointer, but that would cost space and time,
                     * and with care we don't need to.
                     */
                    return (static_cast<const Rep_&> (Bag<T>::_GetRep ()));
                }
                template    <typename T>
                inline  size_t  Bag_Array<T>::GetCapacity () const
                {
                    return (GetRep_ ().fData_.GetCapacity ());
                }
                template    <typename T>
                inline  void    Bag_Array<T>::SetCapacity (size_t slotsAlloced)
                {
                    GetRep_ ().fData_.SetCapacity (slotsAlloced);
                }

            }
        }
    }
}

#endif /* _Stroika_Foundation_Containers_Concrete_Bag_Array_inl_ */
<|endoftext|>


<commit_before>/* $Id$
 *
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements. See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to you under the Apache License, Version
 * 2.0 (the "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <gtest/gtest.h>
#include "common/EtchInt32.h"
#include "common/EtchNative.h"
#include "common/EtchNativeArray.h"

TEST(EtchNativeArrayTest, Constructor_Default) {
  EtchNativeArray<EtchInt32*, EtchInt32::TYPE_ID>* na =
    new EtchNativeArray<EtchInt32*, EtchInt32::TYPE_ID>(10);
    delete na;
}

TEST(EtchNativeArrayTest, Constructor_Array) {

    EtchInt32* int1 = new EtchInt32(42);
    EtchInt32* int2  = new EtchInt32(43);

    EtchNativeArray<EtchInt32*, EtchInt32::TYPE_ID>* na1 =
      new EtchNativeArray<EtchInt32*, EtchInt32::TYPE_ID>(2);

    na1->set(0, int1);
    na1->set(1, int2);

    EXPECT_TRUE(na1->getObjectTypeId() == (EtchNativeArray<EtchInt32,EtchInt32::TYPE_ID>::TYPE_ID));

    EtchInt32* value = NULL;
    int i = 0;
    for(i = 0; i < 2; i++) {
      status_t ret = na1->get(i, &value);
      ASSERT_EQ(ETCH_OK, ret);
      ASSERT_EQ(42 + i, value->get());
    }

    status_t ret = na1->get(i, &value);
    ASSERT_EQ(ETCH_ERANGE, ret);

    delete na1;
    delete int1;
    delete int2;
}

TEST(EtchNativeArrayTest, setget) {

    EtchInt32* int1 = new EtchInt32(42);
    EtchInt32* int2 = new EtchInt32(43);
    EtchNativeArray<EtchInt32*, EtchInt32::TYPE_ID>* na1 =
      new EtchNativeArray<EtchInt32*, EtchInt32::TYPE_ID>(2);
    EXPECT_TRUE(na1->getObjectTypeId() == (EtchNativeArray<EtchInt32, EtchInt32::TYPE_ID>::TYPE_ID));

    na1->set(0, int1);
    na1->set(1, int2);

    EtchInt32* value = NULL;
    int i = 0;
    for(i = 0; i < 2; i++) {
      status_t ret = na1->get(i, &value);
      ASSERT_EQ(ETCH_OK, ret);
      ASSERT_EQ(42 + i, value->get());
    }

    EtchInt32* newValue = new EtchInt32(44);

    na1->set(1, newValue);

    status_t ret = na1->get(1, &value);
    ASSERT_EQ(ETCH_OK, ret);
    ASSERT_EQ(44, newValue->get());

    //Test setget of block
    EtchNativeArray<EtchInt32*, EtchInt32::TYPE_ID> *native_array = new EtchNativeArray<EtchInt32*, EtchInt32::TYPE_ID> (2);
    EtchInt32* int3 = new EtchInt32[2]();
    int3[0].set(2);
    int3[1].set(4);

    ret = native_array->set(0,NULL,0,0,0);
    EXPECT_TRUE(ret == ETCH_EINVAL);

    ret = native_array->get(0,NULL,0,0,0);
    EXPECT_TRUE(ret == ETCH_EINVAL);

    ret = native_array->set(0,&int3,2,0,2);
    EXPECT_TRUE(ret == ETCH_OK);

    ret = native_array->get(0,&int1,2,0,2);
    EXPECT_TRUE(ret == ETCH_OK);

    EXPECT_TRUE(int1[0].get() == 2);
    EXPECT_TRUE(int1[1].get() == 4);

    //Test setget of block of native type
    EtchNativeArray<int, EtchNative::INT32> *native_array2 = new EtchNativeArray<int, EtchNative::INT32> (2);
    int int4[2];
    int int5[2];
    int4[0] = 3;
    int4[1] = 5;

    ret = native_array2->set(0,NULL,0,0,0);
    EXPECT_TRUE(ret == ETCH_EINVAL);

    ret = native_array2->get(0,NULL,0,0,0);
    EXPECT_TRUE(ret == ETCH_EINVAL);

    ret = native_array2->set(0,(int*) int4,2,0,2);
    EXPECT_TRUE(ret == ETCH_OK);

    ret = native_array2->get(0,(int* )int5,2,0,2);
    EXPECT_TRUE(ret == ETCH_OK);

    EXPECT_TRUE(int5[0] == 3);
    EXPECT_TRUE(int5[1] == 5);

    //index out of bounds
    ret = native_array2->set(5,(int*) int4,2,0,2);
    EXPECT_TRUE(ret == ETCH_ERANGE);

    //buffer size smaller then count
    ret = native_array2->set(0,(int*) int4,1,0,2);
    EXPECT_TRUE(ret == ETCH_ERANGE);

    //offset + count out of range
    ret = native_array2->set(0,(int*) int4,2,2,2);
    EXPECT_TRUE(ret == ETCH_ERANGE);

    //index out of bounds
    ret = native_array2->get(5,(int*) int5,2,0,2);
    EXPECT_TRUE(ret == ETCH_ERANGE);

    //buffer size smaller then count
    ret = native_array2->get(0,(int*) int5,1,0,2);
    EXPECT_TRUE(ret == ETCH_ERANGE);

    //offset + count out of range
    ret = native_array2->set(0,(int*) int5,2,2,2);
    EXPECT_TRUE(ret == ETCH_ERANGE);

    delete[] int3;
    delete na1;
    delete int2;
    delete newValue;
    delete native_array;
    delete native_array2;
}
<commit_msg>ETCH-139 EtchNativeArray<commit_after>/* $Id$
 *
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements. See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to you under the Apache License, Version
 * 2.0 (the "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <gtest/gtest.h>
#include "common/EtchInt32.h"
#include "common/EtchNative.h"
#include "common/EtchNativeArray.h"

TEST(EtchNativeArrayTest, Constructor_Default) {
  EtchNativeArray<EtchInt32*, EtchInt32::TYPE_ID>* na =
    new EtchNativeArray<EtchInt32*, EtchInt32::TYPE_ID>(10);
    delete na;
}

TEST(EtchNativeArrayTest, Constructor_Array) {

    EtchInt32* int1 = new EtchInt32(42);
    EtchInt32* int2  = new EtchInt32(43);

    EtchNativeArray<EtchInt32*, EtchInt32::TYPE_ID>* na1 =
      new EtchNativeArray<EtchInt32*, EtchInt32::TYPE_ID>(2);

    na1->set(0, int1);
    na1->set(1, int2);

    EXPECT_TRUE(na1->getObjectTypeId() == (EtchNativeArray<EtchInt32,EtchInt32::TYPE_ID>::TYPE_ID));

    EtchInt32* value = NULL;
    int i = 0;
    for(i = 0; i < 2; i++) {
      status_t ret = na1->get(i, &value);
      ASSERT_EQ(ETCH_OK, ret);
      ASSERT_EQ(42 + i, value->get());
    }

    status_t ret = na1->get(i, &value);
    ASSERT_EQ(ETCH_ERANGE, ret);

    delete na1;
    delete int1;
    delete int2;
}

TEST(EtchNativeArrayTest, setget) {

    EtchInt32* int1 = new EtchInt32(42);
    EtchInt32* int2 = new EtchInt32(43);
    EtchNativeArray<EtchInt32*, EtchInt32::TYPE_ID>* na1 =
      new EtchNativeArray<EtchInt32*, EtchInt32::TYPE_ID>(2);
    EXPECT_TRUE(na1->getObjectTypeId() == (EtchNativeArray<EtchInt32, EtchInt32::TYPE_ID>::TYPE_ID));

    na1->set(0, int1);
    na1->set(1, int2);

    EtchInt32* value = NULL;
    int i = 0;
    for(i = 0; i < 2; i++) {
      status_t ret = na1->get(i, &value);
      ASSERT_EQ(ETCH_OK, ret);
      ASSERT_EQ(42 + i, value->get());
    }

    EtchInt32* newValue = new EtchInt32(44);

    na1->set(1, newValue);

    status_t ret = na1->get(1, &value);
    ASSERT_EQ(ETCH_OK, ret);
    ASSERT_EQ(44, newValue->get());

    //Test setget of block
    EtchNativeArray<EtchInt32*, EtchInt32::TYPE_ID> *native_array = new EtchNativeArray<EtchInt32*, EtchInt32::TYPE_ID> (2);
    EtchInt32** int3 = new EtchInt32*[2];
    int3[0] = new EtchInt32();
    int3[1] = new EtchInt32();

    int3[0]->set(2);
    int3[1]->set(4);

    ret = native_array->set(0,NULL,0,0,0);
    EXPECT_TRUE(ret == ETCH_EINVAL);

    ret = native_array->get(0,NULL,0,0,0);
    EXPECT_TRUE(ret == ETCH_EINVAL);

    ret = native_array->set(0,int3,2,0,2);
    EXPECT_TRUE(ret == ETCH_OK);

    EtchInt32** int6 = new EtchInt32*[2];
    ret = native_array->get(0,int6,2,0,2);
    EXPECT_TRUE(ret == ETCH_OK);

    EXPECT_TRUE(int6[0]->get() == 2);
    EXPECT_TRUE(int6[1]->get() == 4);

    //Test setget of block of native type
    EtchNativeArray<int, EtchNative::INT32> *native_array2 = new EtchNativeArray<int, EtchNative::INT32> (2);
    int int4[2];
    int int5[2];
    int4[0] = 3;
    int4[1] = 5;

    ret = native_array2->set(0,NULL,0,0,0);
    EXPECT_TRUE(ret == ETCH_EINVAL);

    ret = native_array2->get(0,NULL,0,0,0);
    EXPECT_TRUE(ret == ETCH_EINVAL);

    ret = native_array2->set(0,(int*) int4,2,0,2);
    EXPECT_TRUE(ret == ETCH_OK);

    ret = native_array2->get(0,(int* )int5,2,0,2);
    EXPECT_TRUE(ret == ETCH_OK);

    EXPECT_TRUE(int5[0] == 3);
    EXPECT_TRUE(int5[1] == 5);

    //index out of bounds
    ret = native_array2->set(5,(int*) int4,2,0,2);
    EXPECT_TRUE(ret == ETCH_ERANGE);

    //buffer size smaller then count
    ret = native_array2->set(0,(int*) int4,1,0,2);
    EXPECT_TRUE(ret == ETCH_ERANGE);

    //offset + count out of range
    ret = native_array2->set(0,(int*) int4,2,2,2);
    EXPECT_TRUE(ret == ETCH_ERANGE);

    //index out of bounds
    ret = native_array2->get(5,(int*) int5,2,0,2);
    EXPECT_TRUE(ret == ETCH_ERANGE);

    //buffer size smaller then count
    ret = native_array2->get(0,(int*) int5,1,0,2);
    EXPECT_TRUE(ret == ETCH_ERANGE);

    //offset + count out of range
    ret = native_array2->set(0,(int*) int5,2,2,2);
    EXPECT_TRUE(ret == ETCH_ERANGE);

    delete int3[0];
    delete int3[1];
    delete[] int3;
    delete[] int6;
    delete na1;
    delete int1;
    delete int2;
    delete newValue;
    delete native_array;
    delete native_array2;
}
<|endoftext|>


<commit_before>////////////////////////////////////////////////////////////////////////////////
// taskwarrior - a command line task list manager.
//
// Copyright 2006-2011, Paul Beckingham, Federico Hernandez.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
// http://www.opensource.org/licenses/mit-license.php
//
////////////////////////////////////////////////////////////////////////////////

#include <iostream>
#include <sstream>
#include <vector>
#include <string>
#include <stdlib.h>
#include <inttypes.h>
#include <Context.h>
#include <main.h>
#include <text.h>
#include <util.h>
#include <cmake.h>

extern Context context;

////////////////////////////////////////////////////////////////////////////////
bool taskDiff (const Task& before, const Task& after)
{
  // Attributes are all there is, so figure the different attribute names
  // between before and after.
  std::vector <std::string> beforeAtts;
  Task::const_iterator att;
  for (att = before.begin (); att != before.end (); ++att)
    beforeAtts.push_back (att->first);

  std::vector <std::string> afterAtts;
  for (att = after.begin (); att != after.end (); ++att)
    afterAtts.push_back (att->first);

  std::vector <std::string> beforeOnly;
  std::vector <std::string> afterOnly;
  listDiff (beforeAtts, afterAtts, beforeOnly, afterOnly);

  if (beforeOnly.size () !=
      afterOnly.size ())
    return true;

  std::vector <std::string>::iterator name;
  for (name = beforeAtts.begin (); name != beforeAtts.end (); ++name)
    if (*name              != "uuid" &&
        before.get (*name) != after.get (*name))
      return true;

  return false;
}

////////////////////////////////////////////////////////////////////////////////
std::string taskDifferences (const Task& before, const Task& after)
{
  // Attributes are all there is, so figure the different attribute names
  // between before and after.
  std::vector <std::string> beforeAtts;
  Task::const_iterator att;
  for (att = before.begin (); att != before.end (); ++att)
    beforeAtts.push_back (att->first);

  std::vector <std::string> afterAtts;
  for (att = after.begin (); att != after.end (); ++att)
    afterAtts.push_back (att->first);

  std::vector <std::string> beforeOnly;
  std::vector <std::string> afterOnly;
  listDiff (beforeAtts, afterAtts, beforeOnly, afterOnly);

  // Now start generating a description of the differences.
  std::stringstream out;
  std::vector <std::string>::iterator name;
  for (name = beforeOnly.begin (); name != beforeOnly.end (); ++name)
    out << "  - "
        << ucFirst(*name)
        << " will be deleted.\n";

  for (name = afterOnly.begin (); name != afterOnly.end (); ++name)
  {
    if (*name == "depends")
    {
      std::vector <int> deps_after;
      after.getDependencies (deps_after);
      std::string to;
      join (to, ", ", deps_after);

      out << "  - "
          << "Dependencies"
          << " will be set to '"
          << to
          << "'.\n";
    }
    else
      out << "  - "
          << ucFirst(*name)
          << " will be set to '"
          << renderAttribute (*name, after.get (*name))
          << "'.\n";
  }

  for (name = beforeAtts.begin (); name != beforeAtts.end (); ++name)
    if (*name              != "uuid" &&
        before.get (*name) != after.get (*name))
    {
      if (*name == "depends")
      {
        std::vector <int> deps_before;
        before.getDependencies (deps_before);
        std::string from;
        join (from, ", ", deps_before);

        std::vector <int> deps_after;
        after.getDependencies (deps_after);
        std::string to;
        join (to, ", ", deps_after);

        out << "  - "
            << "Dependencies"
            << " will be changed from '"
            << from
            << "' to '"
            << to
            << "'.\n";
      }
      else
        out << "  - "
            << ucFirst(*name)
            << " will be changed from '"
            << renderAttribute (*name, before.get (*name))
            << "' to '"
            << renderAttribute (*name, after.get (*name))
            << "'.\n";
    }

  // Shouldn't just say nothing.
  if (out.str ().length () == 0)
    out << "  - No changes will be made.\n";

  return out.str ();
}

////////////////////////////////////////////////////////////////////////////////
std::string taskInfoDifferences (const Task& before, const Task& after)
{
  // Attributes are all there is, so figure the different attribute names
  // between before and after.
  std::vector <std::string> beforeAtts;
  Task::const_iterator att;
  for (att = before.begin (); att != before.end (); ++att)
    beforeAtts.push_back (att->first);

  std::vector <std::string> afterAtts;
  for (att = after.begin (); att != after.end (); ++att)
    afterAtts.push_back (att->first);

  std::vector <std::string> beforeOnly;
  std::vector <std::string> afterOnly;
  listDiff (beforeAtts, afterAtts, beforeOnly, afterOnly);

  // Now start generating a description of the differences.
  std::stringstream out;
  std::vector <std::string>::iterator name;
  for (name = beforeOnly.begin (); name != beforeOnly.end (); ++name)
  {
    if (*name == "depends")
    {
        std::vector <int> deps_before;
        before.getDependencies (deps_before);
        std::string from;
        join (from, ", ", deps_before);

        out << "Dependencies '"
            << from
            << "' deleted.\n";
    }
    else if (name->substr (0, 11) == "annotation_")
    {
      out << "Annotation '"
          << before.get (*name)
          << "' deleted.\n";
    }
    else
    {
      out << ucFirst (*name)
          << " deleted.\n";
    }
  }

  for (name = afterOnly.begin (); name != afterOnly.end (); ++name)
  {
    if (*name == "depends")
    {
      std::vector <int> deps_after;
      after.getDependencies (deps_after);
      std::string to;
      join (to, ", ", deps_after);

      out << "Dependencies"
          << " set to '"
          << to
          << "'.\n";
    }
    else if (name->substr (0, 11) == "annotation_")
    {
      out << "Annotation of '"
          << after.get (*name)
          << "' added.\n";
    }
    else
      out << ucFirst(*name)
          << " set to '"
          << renderAttribute (*name, after.get (*name))
          << "'.\n";
  }

  for (name = beforeAtts.begin (); name != beforeAtts.end (); ++name)
    if (*name              != "uuid" &&
        before.get (*name) != after.get (*name) &&
        before.get (*name) != "" && after.get (*name) != "")
    {
      if (*name == "depends")
      {
        std::vector <int> deps_before;
        before.getDependencies (deps_before);
        std::string from;
        join (from, ", ", deps_before);

        std::vector <int> deps_after;
        after.getDependencies (deps_after);
        std::string to;
        join (to, ", ", deps_after);

        out << "Dependencies"
            << " changed from '"
            << from
            << "' to '"
            << to
            << "'.\n";
      }
      else if (name->substr (0, 11) == "annotation_")
      {
        out << "Annotation changed to '"
            << after.get (*name)
            << "'.\n";
      }
      else
        out << ucFirst(*name)
            << " changed from '"
            << renderAttribute (*name, before.get (*name))
            << "' to '"
            << renderAttribute (*name, after.get (*name))
            << "'.\n";
    }

  // Shouldn't just say nothing.
  if (out.str ().length () == 0)
    out << "No changes made.\n";

  return out.str ();
}

////////////////////////////////////////////////////////////////////////////////
std::string renderAttribute (const std::string& name, const std::string& value)
{
  Column* col = context.columns[name];
  if (col                    &&
      col->type () == "date" &&
      value != "")
  {
    Date d ((time_t)strtol (value.c_str (), NULL, 10));
    return d.toString (context.config.get ("dateformat"));
  }

  return value;
}

////////////////////////////////////////////////////////////////////////////////
// Implements:
//    <string>
void feedback_affected (const std::string& effect)
{
  if (context.verbose ("affected") ||
      context.config.getBoolean ("echo.command")) // Deprecated 2.0
  {
    std::cout << effect << "\n";
  }
}

////////////////////////////////////////////////////////////////////////////////
// Implements:
//    Deleted 3 tasks
//
// The 'effect' string should contain:
//    {1}    Quantity
void feedback_affected (const std::string& effect, int quantity)
{
  if (context.verbose ("affected") ||
      context.config.getBoolean ("echo.command")) // Deprecated 2.0
  {
    std::cout << format (effect, quantity)
              << "\n";
  }
}

////////////////////////////////////////////////////////////////////////////////
// Implements:
//    Deleting task 123 'This is a test'
//
// The 'effect' string should contain:
//    {1}    ID
//    {2}    Description
void feedback_affected (const std::string& effect, const Task& task)
{
  if (context.verbose ("affected") ||
      context.config.getBoolean ("echo.command")) // Deprecated 2.0
  {
    if (task.id)
      std::cout << format (effect, task.id, task.get ("description"))
                << "\n";
    else
      std::cout << format (effect, task.get ("uuid"), task.get ("description"))
                << "\n";
  }
}

////////////////////////////////////////////////////////////////////////////////

<commit_msg>Feedback<commit_after>////////////////////////////////////////////////////////////////////////////////
// taskwarrior - a command line task list manager.
//
// Copyright 2006-2011, Paul Beckingham, Federico Hernandez.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
// http://www.opensource.org/licenses/mit-license.php
//
////////////////////////////////////////////////////////////////////////////////

#include <iostream>
#include <algorithm>
#include <sstream>
#include <vector>
#include <string>
#include <stdlib.h>
#include <inttypes.h>
#include <Context.h>
#include <main.h>
#include <text.h>
#include <util.h>
#include <cmake.h>

extern Context context;

////////////////////////////////////////////////////////////////////////////////
bool taskDiff (const Task& before, const Task& after)
{
  // Attributes are all there is, so figure the different attribute names
  // between before and after.
  std::vector <std::string> beforeAtts;
  Task::const_iterator att;
  for (att = before.begin (); att != before.end (); ++att)
    beforeAtts.push_back (att->first);

  std::vector <std::string> afterAtts;
  for (att = after.begin (); att != after.end (); ++att)
    afterAtts.push_back (att->first);

  std::vector <std::string> beforeOnly;
  std::vector <std::string> afterOnly;
  listDiff (beforeAtts, afterAtts, beforeOnly, afterOnly);

  if (beforeOnly.size () !=
      afterOnly.size ())
    return true;

  std::vector <std::string>::iterator name;
  for (name = beforeAtts.begin (); name != beforeAtts.end (); ++name)
    if (*name              != "uuid" &&
        before.get (*name) != after.get (*name))
      return true;

  return false;
}

////////////////////////////////////////////////////////////////////////////////
std::string taskDifferences (const Task& before, const Task& after)
{
  // Attributes are all there is, so figure the different attribute names
  // between before and after.
  std::vector <std::string> beforeAtts;
  Task::const_iterator att;
  for (att = before.begin (); att != before.end (); ++att)
    beforeAtts.push_back (att->first);

  std::vector <std::string> afterAtts;
  for (att = after.begin (); att != after.end (); ++att)
    afterAtts.push_back (att->first);

  std::vector <std::string> beforeOnly;
  std::vector <std::string> afterOnly;
  listDiff (beforeAtts, afterAtts, beforeOnly, afterOnly);

  // Now start generating a description of the differences.
  std::stringstream out;
  std::vector <std::string>::iterator name;
  for (name = beforeOnly.begin (); name != beforeOnly.end (); ++name)
    out << "  - "
        << ucFirst(*name)
        << " will be deleted.\n";

  for (name = afterOnly.begin (); name != afterOnly.end (); ++name)
  {
    if (*name == "depends")
    {
      std::vector <int> deps_after;
      after.getDependencies (deps_after);
      std::string to;
      join (to, ", ", deps_after);

      out << "  - "
          << "Dependencies"
          << " will be set to '"
          << to
          << "'.\n";
    }
    else
      out << "  - "
          << ucFirst(*name)
          << " will be set to '"
          << renderAttribute (*name, after.get (*name))
          << "'.\n";
  }

  for (name = beforeAtts.begin (); name != beforeAtts.end (); ++name)
  {
    // Ignore UUID differences, and find values that changed, but are not also
    // in the beforeOnly and afterOnly lists, which have been handled above..
    if (*name              != "uuid" &&
        before.get (*name) != after.get (*name) &&
        std::find (beforeOnly.begin (), beforeOnly.end (), *name) == beforeOnly.end () &&
        std::find (afterOnly.begin (),  afterOnly.end (),  *name) == afterOnly.end ())
    {
      if (*name == "depends")
      {
        std::vector <int> deps_before;
        before.getDependencies (deps_before);
        std::string from;
        join (from, ", ", deps_before);

        std::vector <int> deps_after;
        after.getDependencies (deps_after);
        std::string to;
        join (to, ", ", deps_after);

        out << "  - "
            << "Dependencies"
            << " will be changed from '"
            << from
            << "' to '"
            << to
            << "'.\n";
      }
      else
        out << "  - "
            << ucFirst(*name)
            << " will be changed from '"
            << renderAttribute (*name, before.get (*name))
            << "' to '"
            << renderAttribute (*name, after.get (*name))
            << "'.\n";
    }
  }

  // Shouldn't just say nothing.
  if (out.str ().length () == 0)
    out << "  - No changes will be made.\n";

  return out.str ();
}

////////////////////////////////////////////////////////////////////////////////
std::string taskInfoDifferences (const Task& before, const Task& after)
{
  // Attributes are all there is, so figure the different attribute names
  // between before and after.
  std::vector <std::string> beforeAtts;
  Task::const_iterator att;
  for (att = before.begin (); att != before.end (); ++att)
    beforeAtts.push_back (att->first);

  std::vector <std::string> afterAtts;
  for (att = after.begin (); att != after.end (); ++att)
    afterAtts.push_back (att->first);

  std::vector <std::string> beforeOnly;
  std::vector <std::string> afterOnly;
  listDiff (beforeAtts, afterAtts, beforeOnly, afterOnly);

  // Now start generating a description of the differences.
  std::stringstream out;
  std::vector <std::string>::iterator name;
  for (name = beforeOnly.begin (); name != beforeOnly.end (); ++name)
  {
    if (*name == "depends")
    {
        std::vector <int> deps_before;
        before.getDependencies (deps_before);
        std::string from;
        join (from, ", ", deps_before);

        out << "Dependencies '"
            << from
            << "' deleted.\n";
    }
    else if (name->substr (0, 11) == "annotation_")
    {
      out << "Annotation '"
          << before.get (*name)
          << "' deleted.\n";
    }
    else
    {
      out << ucFirst (*name)
          << " deleted.\n";
    }
  }

  for (name = afterOnly.begin (); name != afterOnly.end (); ++name)
  {
    if (*name == "depends")
    {
      std::vector <int> deps_after;
      after.getDependencies (deps_after);
      std::string to;
      join (to, ", ", deps_after);

      out << "Dependencies"
          << " set to '"
          << to
          << "'.\n";
    }
    else if (name->substr (0, 11) == "annotation_")
    {
      out << "Annotation of '"
          << after.get (*name)
          << "' added.\n";
    }
    else
      out << ucFirst(*name)
          << " set to '"
          << renderAttribute (*name, after.get (*name))
          << "'.\n";
  }

  for (name = beforeAtts.begin (); name != beforeAtts.end (); ++name)
    if (*name              != "uuid" &&
        before.get (*name) != after.get (*name) &&
        before.get (*name) != "" && after.get (*name) != "")
    {
      if (*name == "depends")
      {
        std::vector <int> deps_before;
        before.getDependencies (deps_before);
        std::string from;
        join (from, ", ", deps_before);

        std::vector <int> deps_after;
        after.getDependencies (deps_after);
        std::string to;
        join (to, ", ", deps_after);

        out << "Dependencies"
            << " changed from '"
            << from
            << "' to '"
            << to
            << "'.\n";
      }
      else if (name->substr (0, 11) == "annotation_")
      {
        out << "Annotation changed to '"
            << after.get (*name)
            << "'.\n";
      }
      else
        out << ucFirst(*name)
            << " changed from '"
            << renderAttribute (*name, before.get (*name))
            << "' to '"
            << renderAttribute (*name, after.get (*name))
            << "'.\n";
    }

  // Shouldn't just say nothing.
  if (out.str ().length () == 0)
    out << "No changes made.\n";

  return out.str ();
}

////////////////////////////////////////////////////////////////////////////////
std::string renderAttribute (const std::string& name, const std::string& value)
{
  Column* col = context.columns[name];
  if (col                    &&
      col->type () == "date" &&
      value != "")
  {
    Date d ((time_t)strtol (value.c_str (), NULL, 10));
    return d.toString (context.config.get ("dateformat"));
  }

  return value;
}

////////////////////////////////////////////////////////////////////////////////
// Implements:
//    <string>
void feedback_affected (const std::string& effect)
{
  if (context.verbose ("affected") ||
      context.config.getBoolean ("echo.command")) // Deprecated 2.0
  {
    std::cout << effect << "\n";
  }
}

////////////////////////////////////////////////////////////////////////////////
// Implements:
//    Deleted 3 tasks
//
// The 'effect' string should contain:
//    {1}    Quantity
void feedback_affected (const std::string& effect, int quantity)
{
  if (context.verbose ("affected") ||
      context.config.getBoolean ("echo.command")) // Deprecated 2.0
  {
    std::cout << format (effect, quantity)
              << "\n";
  }
}

////////////////////////////////////////////////////////////////////////////////
// Implements:
//    Deleting task 123 'This is a test'
//
// The 'effect' string should contain:
//    {1}    ID
//    {2}    Description
void feedback_affected (const std::string& effect, const Task& task)
{
  if (context.verbose ("affected") ||
      context.config.getBoolean ("echo.command")) // Deprecated 2.0
  {
    if (task.id)
      std::cout << format (effect, task.id, task.get ("description"))
                << "\n";
    else
      std::cout << format (effect, task.get ("uuid"), task.get ("description"))
                << "\n";
  }
}

////////////////////////////////////////////////////////////////////////////////

<|endoftext|>


<commit_before>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkWedgeMark.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/

#include "vtkWedgeMark.h"
#include "vtkBrush.h"
#include "vtkContext2D.h"
#include "vtkMarkUtil.h"
#include "vtkObjectFactory.h"
#include "vtkPen.h"
#include "vtkInformationDoubleKey.h"
#include "vtkInformationStringKey.h"
#include "vtkInformation.h"

vtkInformationKeyMacro(vtkWedgeMark,ANGLE,Double);
vtkInformationKeyMacro(vtkWedgeMark,INNER_RADIUS,Double);
vtkInformationKeyMacro(vtkWedgeMark,FILL_STYLE,String);

//-----------------------------------------------------------------------------
vtkCxxRevisionMacro(vtkWedgeMark, "1.1");
vtkStandardNewMacro(vtkWedgeMark);

// ----------------------------------------------------------------------------
vtkWedgeMark::vtkWedgeMark()
{
  // this->Information created in vtkMark

  // add the default keys.
  this->AddWedgeDefault();
}

// ----------------------------------------------------------------------------
vtkWedgeMark::~vtkWedgeMark()
{
}

//-----------------------------------------------------------------------------
bool vtkWedgeMark::Hit(const vtkContextMouseEvent &)
{
  return false;
}

// ----------------------------------------------------------------------------
void vtkWedgeMark::AddWedgeDefault()
{
  // 1. fill style is a categorial color
  this->Fields->Set(vtkWedgeMark::FILL_STYLE(),"categorial");
  // 2. no stroke
}

// ----------------------------------------------------------------------------
int vtkWedgeMark::GetType()
{
  return WEDGE;
}

// ----------------------------------------------------------------------------
double vtkWedgeMark::GetMidAngle()
{
  return 0.0;
}

// ----------------------------------------------------------------------------
double vtkWedgeMark::GetMidRadius()
{
  double innerRadius=0.0;
  if(!this->Fields->Has(vtkWedgeMark::INNER_RADIUS()))
    {
    }
  return 0.0;
}

//-----------------------------------------------------------------------------
bool vtkWedgeMark::Paint(vtkContext2D *painter)
{
  double* left = this->Left.GetArray(this);
  double* bottom = this->Bottom.GetArray(this);
  double* width = this->Width.GetArray(this);
  double* height = this->Height.GetArray(this);
  vtkColor* fillColor = this->FillColor.GetArray(this);
  vtkColor* lineColor = this->LineColor.GetArray(this);
  double* lineWidth = this->LineWidth.GetArray(this);

  double *outerRadius=this->OuterRadius.GetArray(this);
  double *innerRadius=this->InnerRadius.GetArray(this);
  double *startAngle=this->StartAngle.GetArray(this);
  double *stopAngle=this->StopAngle.GetArray(this);
  double *angle=this->Angle.GetArray(this);

  vtkIdType numChildren = this->Data.GetData(this).GetNumberOfChildren();

  double a0=0.0;
  double a1=0.0;
  for (vtkIdType i = 0; i < numChildren; ++i)
    {
    a0=a1;
    a1=angle[i]+a0;

    painter->GetBrush()->SetColorF(fillColor[i].Red,
                                   fillColor[i].Green,
                                   fillColor[i].Blue,
                                   fillColor[i].Alpha);
    painter->GetPen()->SetColorF(lineColor[i].Red,
                                lineColor[i].Green,
                                lineColor[i].Blue,
                                lineColor[i].Alpha);
    if (lineWidth[i] > 0.0)
      {
      painter->GetPen()->SetWidth(lineWidth[i]);
      }
    else
      {
      painter->GetPen()->SetOpacity(0);
      }
    painter->DrawWedge(left[i],bottom[i],outerRadius[i],innerRadius[i],
                       a0,a1);
    }
  return true;
}

//-----------------------------------------------------------------------------
void vtkWedgeMark::PrintSelf(ostream &os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os, indent);
}
<commit_msg>COMP:Silent some warning for now. Some variable in the API are not actually used in this case.<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkWedgeMark.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/

#include "vtkWedgeMark.h"
#include "vtkBrush.h"
#include "vtkContext2D.h"
#include "vtkMarkUtil.h"
#include "vtkObjectFactory.h"
#include "vtkPen.h"
#include "vtkInformationDoubleKey.h"
#include "vtkInformationStringKey.h"
#include "vtkInformation.h"

vtkInformationKeyMacro(vtkWedgeMark,ANGLE,Double);
vtkInformationKeyMacro(vtkWedgeMark,INNER_RADIUS,Double);
vtkInformationKeyMacro(vtkWedgeMark,FILL_STYLE,String);

//-----------------------------------------------------------------------------
vtkCxxRevisionMacro(vtkWedgeMark, "1.2");
vtkStandardNewMacro(vtkWedgeMark);

// ----------------------------------------------------------------------------
vtkWedgeMark::vtkWedgeMark()
{
  // this->Information created in vtkMark

  // add the default keys.
  this->AddWedgeDefault();
}

// ----------------------------------------------------------------------------
vtkWedgeMark::~vtkWedgeMark()
{
}

//-----------------------------------------------------------------------------
bool vtkWedgeMark::Hit(const vtkContextMouseEvent &)
{
  return false;
}

// ----------------------------------------------------------------------------
void vtkWedgeMark::AddWedgeDefault()
{
  // 1. fill style is a categorial color
  this->Fields->Set(vtkWedgeMark::FILL_STYLE(),"categorial");
  // 2. no stroke
}

// ----------------------------------------------------------------------------
int vtkWedgeMark::GetType()
{
  return WEDGE;
}

// ----------------------------------------------------------------------------
double vtkWedgeMark::GetMidAngle()
{
  return 0.0;
}

// ----------------------------------------------------------------------------
double vtkWedgeMark::GetMidRadius()
{
//  double innerRadius=0.0;
//  if(!this->Fields->Has(vtkWedgeMark::INNER_RADIUS()))
//    {
//    }
  return 0.0;
}

//-----------------------------------------------------------------------------
bool vtkWedgeMark::Paint(vtkContext2D *painter)
{
  double* left = this->Left.GetArray(this);
  double* bottom = this->Bottom.GetArray(this);
  vtkColor* fillColor = this->FillColor.GetArray(this);
  vtkColor* lineColor = this->LineColor.GetArray(this);
  double* lineWidth = this->LineWidth.GetArray(this);

  double *outerRadius=this->OuterRadius.GetArray(this);
  double *innerRadius=this->InnerRadius.GetArray(this);
//  double *startAngle=this->StartAngle.GetArray(this);
//  double *stopAngle=this->StopAngle.GetArray(this);
  double *angle=this->Angle.GetArray(this);

  vtkIdType numChildren = this->Data.GetData(this).GetNumberOfChildren();

  double a0=0.0;
  double a1=0.0;
  for (vtkIdType i = 0; i < numChildren; ++i)
    {
    a0=a1;
    a1=angle[i]+a0;

    painter->GetBrush()->SetColorF(fillColor[i].Red,
                                   fillColor[i].Green,
                                   fillColor[i].Blue,
                                   fillColor[i].Alpha);
    painter->GetPen()->SetColorF(lineColor[i].Red,
                                lineColor[i].Green,
                                lineColor[i].Blue,
                                lineColor[i].Alpha);
    if (lineWidth[i] > 0.0)
      {
      painter->GetPen()->SetWidth(lineWidth[i]);
      }
    else
      {
      painter->GetPen()->SetOpacity(0);
      }
    painter->DrawWedge(left[i],bottom[i],outerRadius[i],innerRadius[i],
                       a0,a1);
    }
  return true;
}

//-----------------------------------------------------------------------------
void vtkWedgeMark::PrintSelf(ostream &os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os, indent);
}
<|endoftext|>


<commit_before>/*============================================================================

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center (DKFZ)
All rights reserved.

Use of this source code is governed by a 3-clause BSD license that can be
found in the LICENSE file.

============================================================================*/
// Testing
#include "mitkTestingMacros.h"
#include "mitkTestFixture.h"

//MITK includes
#include "mitkIOUtil.h"
#include "mitkStandaloneDataStorage.h"
#include "mitkStatisticsToImageRelationRule.h"
#include "mitkArbitraryTimeGeometry.h"
#include "mitkImageStatisticsContainerNodeHelper.h"
#include "mitkImageStatisticsContainerManager.h"
#include "mitkImageStatisticsContainer.h"

class mitkImageStatisticsContainerTestSuite : public mitk::TestFixture
{
    CPPUNIT_TEST_SUITE(mitkImageStatisticsContainerTestSuite);
    MITK_TEST(StatisticNamesIO);
    MITK_TEST(InvalidKey);
    MITK_TEST(TimeSteps);
    MITK_TEST(PrintSelf);
    MITK_TEST(InternalClone);
    MITK_TEST(StatisticNames);
    MITK_TEST(Reset);
    CPPUNIT_TEST_SUITE_END();

private:
    mitk::ImageStatisticsContainer::Pointer m_statisticsContainer;
    mitk::ImageStatisticsContainer::Pointer m_statisticsContainer2;
    mitk::ImageStatisticsContainer::Pointer m_statisticsContainer3;

    mitk::ImageStatisticsContainer::ImageStatisticsObject m_statisticsObject;
    mitk::ImageStatisticsContainer::ImageStatisticsObject m_statisticsObject2;
    mitk::ImageStatisticsContainer::ImageStatisticsObject m_statisticsObject3;

    mitk::ArbitraryTimeGeometry::Pointer m_timeGeometry;

    mitk::Geometry3D::Pointer m_Geometry1;
    mitk::Geometry3D::Pointer m_Geometry2;
    mitk::Geometry3D::Pointer m_Geometry3;
    mitk::Geometry3D::Pointer m_Geometry3_5;
    mitk::Geometry3D::Pointer m_Geometry4;
    mitk::Geometry3D::Pointer m_Geometry5;

    mitk::TimePointType m_Geometry1MinTP;
    mitk::TimePointType m_Geometry2MinTP;
    mitk::TimePointType m_Geometry3MinTP;
    mitk::TimePointType m_Geometry3_5MinTP;
    mitk::TimePointType m_Geometry4MinTP;
    mitk::TimePointType m_Geometry5MinTP;

    mitk::TimePointType m_Geometry1MaxTP;
    mitk::TimePointType m_Geometry2MaxTP;
    mitk::TimePointType m_Geometry3MaxTP;
    mitk::TimePointType m_Geometry3_5MaxTP;
    mitk::TimePointType m_Geometry4MaxTP;
    mitk::TimePointType m_Geometry5MaxTP;

    std::vector<std::string> estimatedDefaultStatisticNames
    {
        "Mean",
        "Median",
        "StandardDeviation",
        "RMS",
        "Max",
        "MaxPosition",
        "Min",
        "MinPosition",
        "#Voxel",
        "Volume [mm^3]",
        "Skewness",
        "Kurtosis",
        "Uniformity",
        "Entropy",
        "MPP",
        "UPP"
    };

public:
    void setUp() override
    {
        m_statisticsContainer = mitk::ImageStatisticsContainer::New();
        m_statisticsContainer2 = mitk::ImageStatisticsContainer::New();
        m_statisticsContainer3 = mitk::ImageStatisticsContainer::New();

        m_Geometry1 = mitk::Geometry3D::New();
        m_Geometry2 = mitk::Geometry3D::New();
        m_Geometry3 = mitk::Geometry3D::New();
        m_Geometry3_5 = mitk::Geometry3D::New();
        m_Geometry4 = mitk::Geometry3D::New();
        m_Geometry5 = mitk::Geometry3D::New();

        m_Geometry1MinTP = 1;
        m_Geometry2MinTP = 2;
        m_Geometry3MinTP = 3;
        m_Geometry3_5MinTP = 3.5;
        m_Geometry4MinTP = 4;
        m_Geometry5MinTP = 5;

        m_Geometry1MaxTP = 1.9;
        m_Geometry2MaxTP = 2.9;
        m_Geometry3MaxTP = 3.9;
        m_Geometry3_5MaxTP = 3.9;
        m_Geometry4MaxTP = 4.9;
        m_Geometry5MaxTP = 5.9;

        m_timeGeometry = mitk::ArbitraryTimeGeometry::New();
        m_timeGeometry->ClearAllGeometries();
        m_timeGeometry->AppendNewTimeStep(m_Geometry1, m_Geometry1MinTP, m_Geometry1MaxTP);
        m_timeGeometry->AppendNewTimeStep(m_Geometry2, m_Geometry2MinTP, m_Geometry2MaxTP);
        m_timeGeometry->AppendNewTimeStep(m_Geometry3, m_Geometry3MinTP, m_Geometry3MaxTP);
        m_timeGeometry->AppendNewTimeStep(m_Geometry4, m_Geometry4MinTP, m_Geometry4MaxTP);
        m_timeGeometry->AppendNewTimeStep(m_Geometry5, m_Geometry5MinTP, m_Geometry5MaxTP);
    }

    void tearDown() override
    {
        m_statisticsContainer->Reset();
        m_statisticsContainer2->Reset();
        m_statisticsContainer3->Reset();

        m_statisticsObject.Reset();
        m_statisticsObject2.Reset();
        m_statisticsObject3.Reset();

        m_timeGeometry->ClearAllGeometries();
    }

    void CreateNodeRelationImage(mitk::BaseData::Pointer statistics, mitk::BaseData::ConstPointer image)
    {
        auto rule = mitk::StatisticsToImageRelationRule::New();
        rule->Connect(statistics, image);
    }

    void StatisticNamesIO()
    {
        auto defaultStatisticNames = mitk::ImageStatisticsContainer::ImageStatisticsObject::GetDefaultStatisticNames();
        for (size_t i = 0; i < estimatedDefaultStatisticNames.size(); i++)
        {
            CPPUNIT_ASSERT_EQUAL_MESSAGE("Estimated default statistics names are not correct.", defaultStatisticNames.at(i), estimatedDefaultStatisticNames.at(i));
        }

        std::string testName = "testName";
        double realTypeTest = 3.14;
        m_statisticsObject.AddStatistic(testName, realTypeTest);
        auto customStatisticNames = m_statisticsObject.GetCustomStatisticNames();
        size_t one = 1;
        CPPUNIT_ASSERT_EQUAL_MESSAGE("Amount of estimated custom statistics names is not correct.", customStatisticNames.size(), one);
        CPPUNIT_ASSERT_EQUAL_MESSAGE("Estimated custom statistics names are not correct.", customStatisticNames.front(), testName);

        auto allStatisticNames = m_statisticsObject.GetAllStatisticNames();
        estimatedDefaultStatisticNames.push_back(testName);
        for (size_t i = 0; i < estimatedDefaultStatisticNames.size(); i++)
        {
            CPPUNIT_ASSERT_EQUAL_MESSAGE("Estimated statistics names are not correct.", allStatisticNames.at(i), estimatedDefaultStatisticNames.at(i));
        }

        auto existingStatisticNames = m_statisticsObject.GetExistingStatisticNames();
        CPPUNIT_ASSERT_EQUAL_MESSAGE("Amount of estimated existing statistics names is not correct.", existingStatisticNames.size(), one);
        CPPUNIT_ASSERT_EQUAL_MESSAGE("Estimated existing statistics names are not correct.", existingStatisticNames.front(), testName);

        m_statisticsObject.Reset();
        CPPUNIT_ASSERT_MESSAGE("Custom statistics names were not removed correctly.", m_statisticsObject.GetCustomStatisticNames().empty());
    }

    void InvalidKey()
    {
        CPPUNIT_ASSERT_THROW_MESSAGE("Exception should have been thrown because key does not exists.", m_statisticsObject.GetValueNonConverted("Test"), mitk::Exception);
    }

    void TimeSteps()
    {
        m_statisticsContainer->SetTimeGeometry(m_timeGeometry);

        m_statisticsContainer->SetStatisticsForTimeStep(0, m_statisticsObject);
        CPPUNIT_ASSERT_EQUAL_MESSAGE("Previous added time step was not saved correctly.", m_statisticsContainer->TimeStepExists(0), true);
        m_statisticsContainer->SetStatisticsForTimeStep(1, m_statisticsObject);
        CPPUNIT_ASSERT_EQUAL_MESSAGE("Previous added time step was not saved correctly.", m_statisticsContainer->TimeStepExists(1), true);
        m_statisticsContainer->SetStatisticsForTimeStep(2, m_statisticsObject);
        CPPUNIT_ASSERT_EQUAL_MESSAGE("Previous added time step was not saved correctly.", m_statisticsContainer->TimeStepExists(2), true);
        m_statisticsContainer->SetStatisticsForTimeStep(3, m_statisticsObject);
        CPPUNIT_ASSERT_EQUAL_MESSAGE("Previous added time step was not saved correctly.", m_statisticsContainer->TimeStepExists(3), true);
        m_statisticsContainer->SetStatisticsForTimeStep(4, m_statisticsObject);
        CPPUNIT_ASSERT_EQUAL_MESSAGE("Previous added time step was not saved correctly.", m_statisticsContainer->TimeStepExists(4), true);

        CPPUNIT_ASSERT_THROW_MESSAGE("Out of timeStep geometry bounds timeStep was added but no exception was thrown.", m_statisticsContainer->SetStatisticsForTimeStep(42, m_statisticsObject), mitk::Exception);

        CPPUNIT_ASSERT_EQUAL_MESSAGE("Statistics container does not contain the right amount of timeSteps.", static_cast<int> (m_statisticsContainer->GetNumberOfTimeSteps()), 5);
    }

    void PrintSelf()
    {
        m_statisticsContainer->SetTimeGeometry(m_timeGeometry);

        m_statisticsObject.AddStatistic("Test", 4.2);

        m_statisticsContainer->SetStatisticsForTimeStep(0, m_statisticsObject);
        m_statisticsContainer->SetStatisticsForTimeStep(1, m_statisticsObject);
        m_statisticsContainer->SetStatisticsForTimeStep(2, m_statisticsObject);
        m_statisticsContainer->SetStatisticsForTimeStep(3, m_statisticsObject);
        m_statisticsContainer->SetStatisticsForTimeStep(4, m_statisticsObject);

        std::stringstream print;
        m_statisticsContainer->Print(print);

        CPPUNIT_ASSERT_EQUAL_MESSAGE("Data was changed.", static_cast<int> (print.str().length()), 1237);
    }

    void InternalClone()
    {
        auto clone = m_statisticsContainer->Clone();

        CPPUNIT_ASSERT_EQUAL_MESSAGE("Internal clone was not cloned correctly.", m_statisticsContainer->GetGeometry(), clone->GetGeometry());
        CPPUNIT_ASSERT_EQUAL_MESSAGE("Internal clone was not cloned correctly.", m_statisticsContainer->GetNumberOfTimeSteps(), clone->GetNumberOfTimeSteps());
    }

    void StatisticNames()
    {
        m_statisticsContainer->SetTimeGeometry(m_timeGeometry);

        m_statisticsObject.AddStatistic("Test", 4.2);
        m_statisticsObject2.AddStatistic("Test2", 4.2);
        m_statisticsObject2.AddStatistic("Test3", 4.2);

        m_statisticsContainer->SetStatisticsForTimeStep(0, m_statisticsObject);
        m_statisticsContainer->SetStatisticsForTimeStep(1, m_statisticsObject);
        m_statisticsContainer->SetStatisticsForTimeStep(2, m_statisticsObject);
        m_statisticsContainer->SetStatisticsForTimeStep(3, m_statisticsObject);
        m_statisticsContainer->SetStatisticsForTimeStep(4, m_statisticsObject);

        m_statisticsContainer->SetStatisticsForTimeStep(0, m_statisticsObject2);
        m_statisticsContainer->SetStatisticsForTimeStep(1, m_statisticsObject2);
        m_statisticsContainer->SetStatisticsForTimeStep(2, m_statisticsObject2);
        m_statisticsContainer->SetStatisticsForTimeStep(3, m_statisticsObject2);
        m_statisticsContainer->SetStatisticsForTimeStep(4, m_statisticsObject2);

        m_statisticsContainer->SetStatisticsForTimeStep(0, m_statisticsObject3);
        m_statisticsContainer->SetStatisticsForTimeStep(1, m_statisticsObject3);
        m_statisticsContainer->SetStatisticsForTimeStep(2, m_statisticsObject3);
        m_statisticsContainer->SetStatisticsForTimeStep(3, m_statisticsObject3);
        m_statisticsContainer->SetStatisticsForTimeStep(4, m_statisticsObject3);

        CPPUNIT_ASSERT_EQUAL_MESSAGE("Estimated statistics names are not correct.", mitk::GetAllStatisticNames(m_statisticsContainer).size(), estimatedDefaultStatisticNames.size() + 1);

        std::vector<mitk::ImageStatisticsContainer::ConstPointer> containers;

        containers.push_back(m_statisticsContainer.GetPointer());
        containers.push_back(m_statisticsContainer2.GetPointer());
        containers.push_back(m_statisticsContainer3.GetPointer());

        CPPUNIT_ASSERT_EQUAL_MESSAGE("Estimated statistics names are not correct.", mitk::GetAllStatisticNames(containers).size(), estimatedDefaultStatisticNames.size() + 1);
    }

    void Reset()
    {
        m_statisticsContainer->SetTimeGeometry(m_timeGeometry);

        m_statisticsObject.AddStatistic("Test", 4.2);

        m_statisticsContainer->SetStatisticsForTimeStep(0, m_statisticsObject);
        m_statisticsContainer->SetStatisticsForTimeStep(1, m_statisticsObject);
        m_statisticsContainer->SetStatisticsForTimeStep(2, m_statisticsObject);
        m_statisticsContainer->SetStatisticsForTimeStep(3, m_statisticsObject);
        m_statisticsContainer->SetStatisticsForTimeStep(4, m_statisticsObject);

        m_statisticsContainer->Reset();

        m_statisticsObject.Reset();

        m_timeGeometry->ClearAllGeometries();

        CPPUNIT_ASSERT_EQUAL_MESSAGE("Statistic object for time step was not deleted correctly.", m_statisticsContainer->GetStatisticsForTimeStep(0).GetExistingStatisticNames().size(), size_t());
        CPPUNIT_ASSERT_EQUAL_MESSAGE("Statistic object for time step was not deleted correctly.", m_statisticsContainer->GetStatisticsForTimeStep(0).GetCustomStatisticNames().size(), size_t());
        CPPUNIT_ASSERT_EQUAL_MESSAGE("Statistic object for time step was not deleted correctly.", m_statisticsContainer->GetStatisticsForTimeStep(1).GetExistingStatisticNames().size(), size_t());
        CPPUNIT_ASSERT_EQUAL_MESSAGE("Statistic object for time step was not deleted correctly.", m_statisticsContainer->GetStatisticsForTimeStep(1).GetCustomStatisticNames().size(), size_t());
        CPPUNIT_ASSERT_EQUAL_MESSAGE("Statistic object for time step was not deleted correctly.", m_statisticsContainer->GetStatisticsForTimeStep(2).GetExistingStatisticNames().size(), size_t());
        CPPUNIT_ASSERT_EQUAL_MESSAGE("Statistic object for time step was not deleted correctly.", m_statisticsContainer->GetStatisticsForTimeStep(2).GetCustomStatisticNames().size(), size_t());
        CPPUNIT_ASSERT_EQUAL_MESSAGE("Statistic object for time step was not deleted correctly.", m_statisticsContainer->GetStatisticsForTimeStep(3).GetExistingStatisticNames().size(), size_t());
        CPPUNIT_ASSERT_EQUAL_MESSAGE("Statistic object for time step was not deleted correctly.", m_statisticsContainer->GetStatisticsForTimeStep(3).GetCustomStatisticNames().size(), size_t());
        CPPUNIT_ASSERT_EQUAL_MESSAGE("Statistic object for time step was not deleted correctly.", m_statisticsContainer->GetStatisticsForTimeStep(4).GetExistingStatisticNames().size(), size_t());
        CPPUNIT_ASSERT_EQUAL_MESSAGE("Statistic object for time step was not deleted correctly.", m_statisticsContainer->GetStatisticsForTimeStep(4).GetCustomStatisticNames().size(), size_t());

        CPPUNIT_ASSERT_EQUAL_MESSAGE("Statistic was not deleted correctly.", m_statisticsObject.HasStatistic("Test"), false);

        CPPUNIT_ASSERT_EQUAL_MESSAGE("Time geometry was not cleared correctly.", m_timeGeometry->IsValid(), false);
    }
};
MITK_TEST_SUITE_REGISTRATION(mitkImageStatisticsContainer)
<commit_msg>Remove CreateNodeRelationImage function<commit_after>/*============================================================================

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center (DKFZ)
All rights reserved.

Use of this source code is governed by a 3-clause BSD license that can be
found in the LICENSE file.

============================================================================*/
// Testing
#include "mitkTestingMacros.h"
#include "mitkTestFixture.h"

//MITK includes
#include "mitkIOUtil.h"
#include "mitkStandaloneDataStorage.h"
#include "mitkStatisticsToImageRelationRule.h"
#include "mitkArbitraryTimeGeometry.h"
#include "mitkImageStatisticsContainerNodeHelper.h"
#include "mitkImageStatisticsContainerManager.h"
#include "mitkImageStatisticsContainer.h"

class mitkImageStatisticsContainerTestSuite : public mitk::TestFixture
{
    CPPUNIT_TEST_SUITE(mitkImageStatisticsContainerTestSuite);
    MITK_TEST(StatisticNamesIO);
    MITK_TEST(InvalidKey);
    MITK_TEST(TimeSteps);
    MITK_TEST(PrintSelf);
    MITK_TEST(InternalClone);
    MITK_TEST(StatisticNames);
    MITK_TEST(Reset);
    CPPUNIT_TEST_SUITE_END();

private:
    mitk::ImageStatisticsContainer::Pointer m_statisticsContainer;
    mitk::ImageStatisticsContainer::Pointer m_statisticsContainer2;
    mitk::ImageStatisticsContainer::Pointer m_statisticsContainer3;

    mitk::ImageStatisticsContainer::ImageStatisticsObject m_statisticsObject;
    mitk::ImageStatisticsContainer::ImageStatisticsObject m_statisticsObject2;
    mitk::ImageStatisticsContainer::ImageStatisticsObject m_statisticsObject3;

    mitk::ArbitraryTimeGeometry::Pointer m_timeGeometry;

    mitk::Geometry3D::Pointer m_Geometry1;
    mitk::Geometry3D::Pointer m_Geometry2;
    mitk::Geometry3D::Pointer m_Geometry3;
    mitk::Geometry3D::Pointer m_Geometry3_5;
    mitk::Geometry3D::Pointer m_Geometry4;
    mitk::Geometry3D::Pointer m_Geometry5;

    mitk::TimePointType m_Geometry1MinTP;
    mitk::TimePointType m_Geometry2MinTP;
    mitk::TimePointType m_Geometry3MinTP;
    mitk::TimePointType m_Geometry3_5MinTP;
    mitk::TimePointType m_Geometry4MinTP;
    mitk::TimePointType m_Geometry5MinTP;

    mitk::TimePointType m_Geometry1MaxTP;
    mitk::TimePointType m_Geometry2MaxTP;
    mitk::TimePointType m_Geometry3MaxTP;
    mitk::TimePointType m_Geometry3_5MaxTP;
    mitk::TimePointType m_Geometry4MaxTP;
    mitk::TimePointType m_Geometry5MaxTP;

    std::vector<std::string> estimatedDefaultStatisticNames
    {
        "Mean",
        "Median",
        "StandardDeviation",
        "RMS",
        "Max",
        "MaxPosition",
        "Min",
        "MinPosition",
        "#Voxel",
        "Volume [mm^3]",
        "Skewness",
        "Kurtosis",
        "Uniformity",
        "Entropy",
        "MPP",
        "UPP"
    };

public:
    void setUp() override
    {
        m_statisticsContainer = mitk::ImageStatisticsContainer::New();
        m_statisticsContainer2 = mitk::ImageStatisticsContainer::New();
        m_statisticsContainer3 = mitk::ImageStatisticsContainer::New();

        m_Geometry1 = mitk::Geometry3D::New();
        m_Geometry2 = mitk::Geometry3D::New();
        m_Geometry3 = mitk::Geometry3D::New();
        m_Geometry3_5 = mitk::Geometry3D::New();
        m_Geometry4 = mitk::Geometry3D::New();
        m_Geometry5 = mitk::Geometry3D::New();

        m_Geometry1MinTP = 1;
        m_Geometry2MinTP = 2;
        m_Geometry3MinTP = 3;
        m_Geometry3_5MinTP = 3.5;
        m_Geometry4MinTP = 4;
        m_Geometry5MinTP = 5;

        m_Geometry1MaxTP = 1.9;
        m_Geometry2MaxTP = 2.9;
        m_Geometry3MaxTP = 3.9;
        m_Geometry3_5MaxTP = 3.9;
        m_Geometry4MaxTP = 4.9;
        m_Geometry5MaxTP = 5.9;

        m_timeGeometry = mitk::ArbitraryTimeGeometry::New();
        m_timeGeometry->ClearAllGeometries();
        m_timeGeometry->AppendNewTimeStep(m_Geometry1, m_Geometry1MinTP, m_Geometry1MaxTP);
        m_timeGeometry->AppendNewTimeStep(m_Geometry2, m_Geometry2MinTP, m_Geometry2MaxTP);
        m_timeGeometry->AppendNewTimeStep(m_Geometry3, m_Geometry3MinTP, m_Geometry3MaxTP);
        m_timeGeometry->AppendNewTimeStep(m_Geometry4, m_Geometry4MinTP, m_Geometry4MaxTP);
        m_timeGeometry->AppendNewTimeStep(m_Geometry5, m_Geometry5MinTP, m_Geometry5MaxTP);
    }

    void tearDown() override
    {
        m_statisticsContainer->Reset();
        m_statisticsContainer2->Reset();
        m_statisticsContainer3->Reset();

        m_statisticsObject.Reset();
        m_statisticsObject2.Reset();
        m_statisticsObject3.Reset();

        m_timeGeometry->ClearAllGeometries();
    }

    }

    void StatisticNamesIO()
    {
        auto defaultStatisticNames = mitk::ImageStatisticsContainer::ImageStatisticsObject::GetDefaultStatisticNames();
        for (size_t i = 0; i < estimatedDefaultStatisticNames.size(); i++)
        {
            CPPUNIT_ASSERT_EQUAL_MESSAGE("Estimated default statistics names are not correct.", defaultStatisticNames.at(i), estimatedDefaultStatisticNames.at(i));
        }

        std::string testName = "testName";
        double realTypeTest = 3.14;
        m_statisticsObject.AddStatistic(testName, realTypeTest);
        auto customStatisticNames = m_statisticsObject.GetCustomStatisticNames();
        size_t one = 1;
        CPPUNIT_ASSERT_EQUAL_MESSAGE("Amount of estimated custom statistics names is not correct.", customStatisticNames.size(), one);
        CPPUNIT_ASSERT_EQUAL_MESSAGE("Estimated custom statistics names are not correct.", customStatisticNames.front(), testName);

        auto allStatisticNames = m_statisticsObject.GetAllStatisticNames();
        estimatedDefaultStatisticNames.push_back(testName);
        for (size_t i = 0; i < estimatedDefaultStatisticNames.size(); i++)
        {
            CPPUNIT_ASSERT_EQUAL_MESSAGE("Estimated statistics names are not correct.", allStatisticNames.at(i), estimatedDefaultStatisticNames.at(i));
        }

        auto existingStatisticNames = m_statisticsObject.GetExistingStatisticNames();
        CPPUNIT_ASSERT_EQUAL_MESSAGE("Amount of estimated existing statistics names is not correct.", existingStatisticNames.size(), one);
        CPPUNIT_ASSERT_EQUAL_MESSAGE("Estimated existing statistics names are not correct.", existingStatisticNames.front(), testName);

        m_statisticsObject.Reset();
        CPPUNIT_ASSERT_MESSAGE("Custom statistics names were not removed correctly.", m_statisticsObject.GetCustomStatisticNames().empty());
    }

    void InvalidKey()
    {
        CPPUNIT_ASSERT_THROW_MESSAGE("Exception should have been thrown because key does not exists.", m_statisticsObject.GetValueNonConverted("Test"), mitk::Exception);
    }

    void TimeSteps()
    {
        m_statisticsContainer->SetTimeGeometry(m_timeGeometry);

        m_statisticsContainer->SetStatisticsForTimeStep(0, m_statisticsObject);
        CPPUNIT_ASSERT_EQUAL_MESSAGE("Previous added time step was not saved correctly.", m_statisticsContainer->TimeStepExists(0), true);
        m_statisticsContainer->SetStatisticsForTimeStep(1, m_statisticsObject);
        CPPUNIT_ASSERT_EQUAL_MESSAGE("Previous added time step was not saved correctly.", m_statisticsContainer->TimeStepExists(1), true);
        m_statisticsContainer->SetStatisticsForTimeStep(2, m_statisticsObject);
        CPPUNIT_ASSERT_EQUAL_MESSAGE("Previous added time step was not saved correctly.", m_statisticsContainer->TimeStepExists(2), true);
        m_statisticsContainer->SetStatisticsForTimeStep(3, m_statisticsObject);
        CPPUNIT_ASSERT_EQUAL_MESSAGE("Previous added time step was not saved correctly.", m_statisticsContainer->TimeStepExists(3), true);
        m_statisticsContainer->SetStatisticsForTimeStep(4, m_statisticsObject);
        CPPUNIT_ASSERT_EQUAL_MESSAGE("Previous added time step was not saved correctly.", m_statisticsContainer->TimeStepExists(4), true);

        CPPUNIT_ASSERT_THROW_MESSAGE("Out of timeStep geometry bounds timeStep was added but no exception was thrown.", m_statisticsContainer->SetStatisticsForTimeStep(42, m_statisticsObject), mitk::Exception);

        CPPUNIT_ASSERT_EQUAL_MESSAGE("Statistics container does not contain the right amount of timeSteps.", static_cast<int> (m_statisticsContainer->GetNumberOfTimeSteps()), 5);
    }

    void PrintSelf()
    {
        m_statisticsContainer->SetTimeGeometry(m_timeGeometry);

        m_statisticsObject.AddStatistic("Test", 4.2);

        m_statisticsContainer->SetStatisticsForTimeStep(0, m_statisticsObject);
        m_statisticsContainer->SetStatisticsForTimeStep(1, m_statisticsObject);
        m_statisticsContainer->SetStatisticsForTimeStep(2, m_statisticsObject);
        m_statisticsContainer->SetStatisticsForTimeStep(3, m_statisticsObject);
        m_statisticsContainer->SetStatisticsForTimeStep(4, m_statisticsObject);

        std::stringstream print;
        m_statisticsContainer->Print(print);

        CPPUNIT_ASSERT_EQUAL_MESSAGE("Data was changed.", static_cast<int> (print.str().length()), 1237);
    }

    void InternalClone()
    {
        auto clone = m_statisticsContainer->Clone();

        CPPUNIT_ASSERT_EQUAL_MESSAGE("Internal clone was not cloned correctly.", m_statisticsContainer->GetGeometry(), clone->GetGeometry());
        CPPUNIT_ASSERT_EQUAL_MESSAGE("Internal clone was not cloned correctly.", m_statisticsContainer->GetNumberOfTimeSteps(), clone->GetNumberOfTimeSteps());
    }

    void StatisticNames()
    {
        m_statisticsContainer->SetTimeGeometry(m_timeGeometry);

        m_statisticsObject.AddStatistic("Test", 4.2);
        m_statisticsObject2.AddStatistic("Test2", 4.2);
        m_statisticsObject2.AddStatistic("Test3", 4.2);

        m_statisticsContainer->SetStatisticsForTimeStep(0, m_statisticsObject);
        m_statisticsContainer->SetStatisticsForTimeStep(1, m_statisticsObject);
        m_statisticsContainer->SetStatisticsForTimeStep(2, m_statisticsObject);
        m_statisticsContainer->SetStatisticsForTimeStep(3, m_statisticsObject);
        m_statisticsContainer->SetStatisticsForTimeStep(4, m_statisticsObject);

        m_statisticsContainer->SetStatisticsForTimeStep(0, m_statisticsObject2);
        m_statisticsContainer->SetStatisticsForTimeStep(1, m_statisticsObject2);
        m_statisticsContainer->SetStatisticsForTimeStep(2, m_statisticsObject2);
        m_statisticsContainer->SetStatisticsForTimeStep(3, m_statisticsObject2);
        m_statisticsContainer->SetStatisticsForTimeStep(4, m_statisticsObject2);

        m_statisticsContainer->SetStatisticsForTimeStep(0, m_statisticsObject3);
        m_statisticsContainer->SetStatisticsForTimeStep(1, m_statisticsObject3);
        m_statisticsContainer->SetStatisticsForTimeStep(2, m_statisticsObject3);
        m_statisticsContainer->SetStatisticsForTimeStep(3, m_statisticsObject3);
        m_statisticsContainer->SetStatisticsForTimeStep(4, m_statisticsObject3);

        CPPUNIT_ASSERT_EQUAL_MESSAGE("Estimated statistics names are not correct.", mitk::GetAllStatisticNames(m_statisticsContainer).size(), estimatedDefaultStatisticNames.size() + 1);

        std::vector<mitk::ImageStatisticsContainer::ConstPointer> containers;

        containers.push_back(m_statisticsContainer.GetPointer());
        containers.push_back(m_statisticsContainer2.GetPointer());
        containers.push_back(m_statisticsContainer3.GetPointer());

        CPPUNIT_ASSERT_EQUAL_MESSAGE("Estimated statistics names are not correct.", mitk::GetAllStatisticNames(containers).size(), estimatedDefaultStatisticNames.size() + 1);
    }

    void Reset()
    {
        m_statisticsContainer->SetTimeGeometry(m_timeGeometry);

        m_statisticsObject.AddStatistic("Test", 4.2);

        m_statisticsContainer->SetStatisticsForTimeStep(0, m_statisticsObject);
        m_statisticsContainer->SetStatisticsForTimeStep(1, m_statisticsObject);
        m_statisticsContainer->SetStatisticsForTimeStep(2, m_statisticsObject);
        m_statisticsContainer->SetStatisticsForTimeStep(3, m_statisticsObject);
        m_statisticsContainer->SetStatisticsForTimeStep(4, m_statisticsObject);

        m_statisticsContainer->Reset();

        m_statisticsObject.Reset();

        m_timeGeometry->ClearAllGeometries();

        CPPUNIT_ASSERT_EQUAL_MESSAGE("Statistic object for time step was not deleted correctly.", m_statisticsContainer->GetStatisticsForTimeStep(0).GetExistingStatisticNames().size(), size_t());
        CPPUNIT_ASSERT_EQUAL_MESSAGE("Statistic object for time step was not deleted correctly.", m_statisticsContainer->GetStatisticsForTimeStep(0).GetCustomStatisticNames().size(), size_t());
        CPPUNIT_ASSERT_EQUAL_MESSAGE("Statistic object for time step was not deleted correctly.", m_statisticsContainer->GetStatisticsForTimeStep(1).GetExistingStatisticNames().size(), size_t());
        CPPUNIT_ASSERT_EQUAL_MESSAGE("Statistic object for time step was not deleted correctly.", m_statisticsContainer->GetStatisticsForTimeStep(1).GetCustomStatisticNames().size(), size_t());
        CPPUNIT_ASSERT_EQUAL_MESSAGE("Statistic object for time step was not deleted correctly.", m_statisticsContainer->GetStatisticsForTimeStep(2).GetExistingStatisticNames().size(), size_t());
        CPPUNIT_ASSERT_EQUAL_MESSAGE("Statistic object for time step was not deleted correctly.", m_statisticsContainer->GetStatisticsForTimeStep(2).GetCustomStatisticNames().size(), size_t());
        CPPUNIT_ASSERT_EQUAL_MESSAGE("Statistic object for time step was not deleted correctly.", m_statisticsContainer->GetStatisticsForTimeStep(3).GetExistingStatisticNames().size(), size_t());
        CPPUNIT_ASSERT_EQUAL_MESSAGE("Statistic object for time step was not deleted correctly.", m_statisticsContainer->GetStatisticsForTimeStep(3).GetCustomStatisticNames().size(), size_t());
        CPPUNIT_ASSERT_EQUAL_MESSAGE("Statistic object for time step was not deleted correctly.", m_statisticsContainer->GetStatisticsForTimeStep(4).GetExistingStatisticNames().size(), size_t());
        CPPUNIT_ASSERT_EQUAL_MESSAGE("Statistic object for time step was not deleted correctly.", m_statisticsContainer->GetStatisticsForTimeStep(4).GetCustomStatisticNames().size(), size_t());

        CPPUNIT_ASSERT_EQUAL_MESSAGE("Statistic was not deleted correctly.", m_statisticsObject.HasStatistic("Test"), false);

        CPPUNIT_ASSERT_EQUAL_MESSAGE("Time geometry was not cleared correctly.", m_timeGeometry->IsValid(), false);
    }
};
MITK_TEST_SUITE_REGISTRATION(mitkImageStatisticsContainer)
<|endoftext|>