Go back to Richel Bilderbeek's homepage.

Go back to Richel Bilderbeek's C++ page.

 

 

 

 

 

(C++) MultiVector

 

STLQt CreatorLubuntu

 

MultiVector is a container class to store elements at indices of any dimensionality.

 

MultiVector is demonstrated/tested with the tool TestMultiVector.

Technical facts

 

 

 

 

 

 

./CppMultiVector/CppMultiVector.pri

 

INCLUDEPATH += \
    ../../Classes/CppMultiVector

SOURCES += \
    ../../Classes/CppMultiVector/multivector.cpp

HEADERS  += \
    ../../Classes/CppMultiVector/multivector.h

OTHER_FILES += \
    ../../Classes/CppMultiVector/Licence.txt

 

 

 

 

 

./CppMultiVector/multivector.h

 

//---------------------------------------------------------------------------
/*
MultiVector, any-dimensional std::vector class
Copyright (C) 2011-2015 Richel Bilderbeek

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS  A PARTICULAR PURPOSE.See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program.If not, see <http://www.gnu.org/licenses/>.
*/
//---------------------------------------------------------------------------
//From http://www.richelbilderbeek.nl/CppMultiVector.htm
//---------------------------------------------------------------------------
#ifndef MULTIVECTOR_H
#define MULTIVECTOR_H

#include <cassert>
#include <iostream>
#include <string>
#include <vector>

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Weffc++"
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
#include <boost/numeric/conversion/cast.hpp>
#pragma GCC diagnostic pop

namespace ribi {

#ifndef NDEBUG
void TestMultiVector() noexcept;
#endif

template <class T>
struct MultiVector
{
  MultiVector() : m_indices{}, m_multivectors{}
  {
    #ifndef NDEBUG
    TestMultiVector();
    #endif
  }

  ///CanRetrieve returns if an index/coordinat can be retrieved
  bool CanRetrieve(const std::vector<int>& indices) const
  {
    assert(!indices.empty());
    if (indices.size() == 1)
    {
      return (indices[0] < boost::numeric_cast<int>(m_indices.size()));
    }
    else
    {
      std::vector<int> copy_indices;
      std::copy(indices.begin() + 1,indices.end(),std::back_inserter(copy_indices));
      if (!(indices[0] < boost::numeric_cast<int>(m_multivectors.size())))
      {
        return false;
      }
      return m_multivectors[ indices[0] ].CanRetrieve(copy_indices);
    }
  }

  ///CreateTable creates a non-recursive table
  const std::vector<std::pair<std::vector<T>,T> > CreateTable() const
  {
    assert(!"TODO");
    std::vector<std::pair<std::vector<T>,T> > v;
    return v;
  }

  const std::vector<T>& PeekIndices() const { return m_indices; }

  const std::vector<MultiVector>& PeekMultiVectors() const { return m_multivectors; }

  ///Retrieve retrieves a stored value at a certain, any-dimensional index/coordinat
  const T& Retrieve(const std::vector<int>& indices) const
  {
    assert(!indices.empty());
    if (!CanRetrieve(indices))
    {
      std::clog << "Breakpoint\n";
    }
    assert(CanRetrieve(indices));
    if (indices.size() == 1)
    {
      assert(indices[0] < boost::numeric_cast<int>(m_indices.size()));
      return m_indices[indices[0] ];
    }
    else
    {
      std::vector<int> copy_indices;
      std::copy(indices.begin() + 1,indices.end(),std::back_inserter(copy_indices));
      assert(indices[0] < boost::numeric_cast<int>(m_multivectors.size()));
      return m_multivectors[ indices[0] ].Retrieve(copy_indices);
    }
  }

  ///Store stores a value at a certain, any-dimensional index/coordinat
  void Store(const std::vector<int>& indices, const T& value)
  {
    assert(!indices.empty());
    const int index = indices[0];
    if (indices.size() == 1)
    {
      if (index + 1 > boost::numeric_cast<int>(m_indices.size()))
      {
        m_indices.resize(index + 1);
      }
      assert(index < boost::numeric_cast<int>(m_indices.size()));
      m_indices[index] = value;
    }
    else
    {
      std::vector<int> copy_indices;
      std::copy(indices.begin() + 1,indices.end(),std::back_inserter(copy_indices));
      if (index + 1 > boost::numeric_cast<int>(m_multivectors.size()))
      {
        m_multivectors.resize(index + 1);
      }
      assert(indices[0] < boost::numeric_cast<int>(m_multivectors.size()));
      m_multivectors[ indices[0] ].Store(copy_indices,value);
    }
  }

  private:
  std::vector<T> m_indices;
  std::vector<MultiVector> m_multivectors;

  public:

  static std::string GetVersion()
  {
    return "1.1";
  }

  std::vector<std::string> GetVersionHistory()
  {
    return {
      "2011-03-02: version 1.0: initial version",
      "2011-03-02: version 1.1: added CanRetrieve and Peek member functions"
    };
  }


};

} //~namespace ribi

#endif // MULTIVECTOR_H

 

 

 

 

 

./CppMultiVector/multivector.cpp

 

//---------------------------------------------------------------------------
/*
MultiVector, any-dimensional std::vector class
Copyright (C) 2011-2015 Richel Bilderbeek

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS  A PARTICULAR PURPOSE.See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program.If not, see <http://www.gnu.org/licenses/>.
*/
//---------------------------------------------------------------------------
//From http://www.richelbilderbeek.nl/CppMultiVector.htm
//---------------------------------------------------------------------------
#include "multivector.h"
#include "testtimer.h"

#ifndef NDEBUG
void ribi::TestMultiVector() noexcept
{
  {
    static bool is_tested{false};
    if (is_tested) return;
    is_tested = true;
  }
  {

  }
  const TestTimer test_timer(__func__,__FILE__,1.0);
  ribi::MultiVector<int> x;
  //1 dimensional
  x.Store( { 0 }, 0);
  x.Store( { 1 }, 1);
  x.Store( { 2 }, 2);
  x.Store( { 3 }, 3);
  x.Store( { 4 }, 4);
  assert(x.Retrieve( { 0 } ) ==  0);
  assert(x.Retrieve( { 1 } ) ==  1);
  assert(x.Retrieve( { 2 } ) ==  2);
  assert(x.Retrieve( { 3 } ) ==  3);
  assert(x.Retrieve( { 4 } ) ==  4);
  //2 dimensional;
  x.Store( { 0,0 },  0);
  x.Store( { 1,1 },  1);
  x.Store( { 2,2 },  4);
  x.Store( { 3,3 },  9);
  x.Store( { 4,4 }, 16);
  assert(x.Retrieve( { 0,0 } ) ==  0);
  assert(x.Retrieve( { 1,1 } ) ==  1);
  assert(x.Retrieve( { 2,2 } ) ==  4);
  assert(x.Retrieve( { 3,3 } ) ==  9);
  assert(x.Retrieve( { 4,4 } ) == 16);
  //3 dimensional;
  x.Store( { 0,0,0 },  0);
  x.Store( { 1,1,1 },  1);
  x.Store( { 2,2,2 },  8);
  x.Store( { 3,3,3 }, 27);
  x.Store( { 4,4,4 }, 54);
  assert(x.Retrieve( { 0,0,0 } ) ==   0);
  assert(x.Retrieve( { 1,1,1 } ) ==   1);
  assert(x.Retrieve( { 2,2,2 } ) ==   8);
  assert(x.Retrieve( { 3,3,3 } ) ==  27);
  assert(x.Retrieve( { 4,4,4 } ) ==  54);
  //4 dimensional;
  x.Store( { 0,0,0,0 },   0);
  x.Store( { 1,1,1,1 },   1);
  x.Store( { 2,2,2,2 },  16);
  x.Store( { 3,3,3,3 },  81);
  x.Store( { 4,4,4,4 }, 216);
  assert(x.Retrieve( { 0,0,0,0 } ) ==   0);
  assert(x.Retrieve( { 1,1,1,1 } ) ==   1);
  assert(x.Retrieve( { 2,2,2,2 } ) ==  16);
  assert(x.Retrieve( { 3,3,3,3 } ) ==  81);
  assert(x.Retrieve( { 4,4,4,4 } ) == 216);
  //5 dimensional;
  x.Store( { 0,0,0,0,0 },   0);
  x.Store( { 1,1,1,1,1 },   1);
  x.Store( { 2,2,2,2,2 },  32);
  x.Store( { 3,3,3,3,3 }, 243);
  x.Store( { 4,4,4,4,4 }, 864);
  assert(x.Retrieve( { 0,0,0,0,0 } ) ==    0);
  assert(x.Retrieve( { 1,1,1,1,1 } ) ==    1);
  assert(x.Retrieve( { 2,2,2,2,2 } ) ==   32);
  assert(x.Retrieve( { 3,3,3,3,3 } ) ==  243);
  assert(x.Retrieve( { 4,4,4,4,4 } ) ==  864);

}
#endif

 

 

 

 

 

Go back to Richel Bilderbeek's C++ page.

Go back to Richel Bilderbeek's homepage.

 

Valid XHTML 1.0 Strict

This page has been created by the tool CodeToHtml