UI-Coordinates: extract PathArray base abstraction into a library class

This commit is contained in:
Fischlurch 2017-09-24 22:41:45 +02:00
parent 4082526ec6
commit 5e1c25aaf5
4 changed files with 351 additions and 82 deletions

View file

@ -39,6 +39,8 @@
**
** @todo WIP 9/2017 first draft ////////////////////////////////////////////////////////////////////////////TICKET #1106 generic UI coordinate system
**
** @note UICoord is designed with immutability in mind; possibly we may decide to disallow assignment.
**
** @see UICoord_test
** @see id-scheme.hpp
** @see view-spec-dsl.hpp
@ -51,11 +53,10 @@
#include "lib/error.hpp"
#include "lib/symbol.hpp"
#include "lib/iter-adapter.hpp"
#include "lib/path-array.hpp"
//#include <boost/noncopyable.hpp>
#include <string>
#include <limits>
//#include <memory>
@ -66,87 +67,8 @@ namespace interact {
using std::string;
using lib::Literal;
// class GlobalCtx;
/**
* @internal Base abstraction for path-like topological coordinates.
*/
class PathArray
{
public:
template<typename...ARGS>
explicit
PathArray (ARGS&& ...args)
{
UNIMPLEMENTED ("initialise path array components");
}
// standard copy operations acceptable
size_t
size() const
{
UNIMPLEMENTED ("path implementation storage");
}
bool
empty() const
{
UNIMPLEMENTED ("path implementation storage");
}
Literal
operator[] (size_t idx)
{
UNIMPLEMENTED ("path implementation storage");
}
protected: /* ==== Iteration control API for IterAdapter ==== */
/** Implementation of Iteration-logic: pull next element. */
friend void
iterNext (const PathArray* src, Literal* pos)
{
++pos;
checkPoint (src,pos);
}
/** Implementation of Iteration-logic: detect iteration end. */
friend bool
checkPoint (const PathArray* src, Literal* pos)
{
REQUIRE (src);
if ((pos != nullptr) && (pos != src->storage_end()))
return true;
else
{
pos = nullptr;
return false;
} }
public:
using iterator = lib::IterAdapter<Literal*, PathArray*>;
using const_iterator = iterator;
iterator begin() const { UNIMPLEMENTED ("content iteration"); }
iterator end() const { UNIMPLEMENTED ("content iteration"); }
friend iterator begin(PathArray const& pa) { return pa.begin();}
friend iterator end (PathArray const& pa) { return pa.end(); }
private:
Literal*
storage_end() const
{
UNIMPLEMENTED ("path implementation storage");
}
};
enum UIPathElm
{
UIC_WINDOW,
@ -166,7 +88,7 @@ namespace interact {
* @todo initial draft as of 9/2017
*/
class UICoord
: public PathArray
: public lib::PathArray
{
public:

165
src/lib/path-array.hpp Normal file
View file

@ -0,0 +1,165 @@
/*
PATH-ARRAY.hpp - sequence of path-like component-IDs in fixed storage
Copyright (C) Lumiera.org
2017, Hermann Vosseler <Ichthyostega@web.de>
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 2 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 FOR 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/** @file path-array.hpp
** Foundation abstraction to implement path-like component sequences.
** This library class can be used to build a path abstraction for data structure access
** or some similar topological coordinate system, like e.g. [UI coordinates](\ref ui-coord.hpp)
** A PathArray is an iterable sequence of literal component IDs, implemented as tuple of `Literal*`
** held in fixed inline storage with possible heap allocated (and thus unlimited) extension storage.
** It offers range checks, standard iteration and array-like indexed component access; as a whole
** it is copyable, while actual components are immutable after construction.
**
** @todo WIP 9/2017 first draft ////////////////////////////////////////////////////////////////////////////TICKET #1106 generic UI coordinate system
**
** @see PathArray_test
** @see UICoord_test
** @see gui::interact::UICoord
** @see view-spec-dsl.hpp
*/
#ifndef LIB_PATH_ARRAY_H
#define LIB_PATH_ARRAY_H
#include "lib/error.hpp"
#include "lib/symbol.hpp"
#include "lib/iter-adapter.hpp"
//#include <boost/noncopyable.hpp>
#include <string>
//#include <memory>
namespace lib {
// using std::unique_ptr;
using std::string;
using lib::Literal;
// class GlobalCtx;
/**
* @internal Base abstraction for path-like topological coordinates.
*/
class PathArray
{
public:
template<typename...ARGS>
explicit
PathArray (ARGS&& ...args)
{
UNIMPLEMENTED ("initialise path array components");
}
// standard copy operations acceptable
size_t
size() const
{
UNIMPLEMENTED ("path implementation storage");
}
bool
empty() const
{
UNIMPLEMENTED ("path implementation storage");
}
operator string() const;
Literal
operator[] (size_t idx)
{
UNIMPLEMENTED ("path implementation storage");
}
protected: /* ==== Iteration control API for IterAdapter ==== */
/** Implementation of Iteration-logic: pull next element. */
friend void
iterNext (const PathArray* src, Literal* pos)
{
++pos;
checkPoint (src,pos);
}
/** Implementation of Iteration-logic: detect iteration end. */
friend bool
checkPoint (const PathArray* src, Literal* pos)
{
REQUIRE (src);
if ((pos != nullptr) && (pos != src->storage_end()))
return true;
else
{
pos = nullptr;
return false;
} }
public:
using iterator = lib::IterAdapter<Literal*, PathArray*>;
using const_iterator = iterator;
iterator begin() const { UNIMPLEMENTED ("content iteration"); }
iterator end() const { UNIMPLEMENTED ("content iteration"); }
friend iterator begin(PathArray const& pa) { return pa.begin();}
friend iterator end (PathArray const& pa) { return pa.end(); }
private:
Literal*
storage_end() const
{
UNIMPLEMENTED ("path implementation storage");
}
};
inline
PathArray::operator string() const
{
if (this->empty()) return "";
string buff;
size_t expectedLen = this->size() * 10;
buff.reserve (expectedLen);
for (Literal elm : *this)
buff += elm + "/";
// chop off last delimiter
size_t len = buff.length();
ASSERT (len >= 1);
buff.resize(len-1);
return buff;
}
}// namespace lib
#endif /*LIB_PATH_ARRAY_H*/

View file

@ -415,6 +415,11 @@ return: 0
END
TEST "path array abstraction" PathArray_test <<END
return: 0
END
TEST "RefArray_test" RefArray_test <<END
return: 0
END

View file

@ -0,0 +1,177 @@
/*
PathArray(Test) - verify container abstraction for a sequence of path elements
Copyright (C) Lumiera.org
2017, Hermann Vosseler <Ichthyostega@web.de>
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 2 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 FOR 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
* *****************************************************/
/** @file path-array-test.cpp
** unit test \ref PathArray_test
*/
#include "lib/test/run.hpp"
#include "lib/test/test-helper.hpp"
#include "lib/path-array.hpp"
//#include "lib/format-cout.hpp"
#include "lib/format-util.hpp"
//#include "lib/idi/entry-id.hpp"
//#include "lib/diff/gen-node.hpp"
#include "lib/util.hpp"
#include <string>
using std::string;
//using lib::idi::EntryID;
//using lib::diff::GenNode;
//using util::isSameObject;
using util::isnil;
using util::join;
namespace lib {
namespace test {
// using lumiera::error::LUMIERA_ERROR_WRONG_TYPE;
using lumiera::error::LUMIERA_ERROR_INDEX_BOUNDS;
using lumiera::error::LUMIERA_ERROR_LOGIC;
namespace { //Test fixture...
}//(End)Test fixture
/******************************************************************************//**
* @test verify abstraction wrapper to handle some char pointers in the way of a
* standard sequence container with iteration and range checks.
*
* @see path-array.hpp
* @see UICoord_test
* @see Navigator
*/
class PathArray_test : public Test
{
virtual void
run (Arg)
{
verify_basics();
verify_iteration();
verify_comparisons();
}
void
verify_basics()
{
PathArray undef;
CHECK (isnil (undef));
PathArray parr{"Γ","Δ","Θ","Ξ","Σ","Ψ","Φ","Ω"};
CHECK (not isnil (parr));
CHECK (8 == parr.size());
// indexed access
CHECK ("Γ" == parr[0]);
CHECK ("Δ" == parr[1]);
CHECK ("Θ" == parr[2]);
CHECK ("Ξ" == parr[3]);
CHECK ("Σ" == parr[4]);
CHECK ("Ψ" == parr[5]);
CHECK ("Φ" == parr[6]);
CHECK ("Ω" == parr[7]);
VERIFY_ERROR (INDEX_BOUNDS, parr[8]);
// string representation
CHECK ("Γ/Δ/Θ/Ξ/Σ/Ψ/Φ/Ω" == string(parr));
// new value can be assigned, but not altered in place
parr = PathArray{nullptr,nullptr,"Θ",nullptr,nullptr,nullptr,"Φ"};
CHECK (7 == parr.size());
// representation is trimmed and filled
CHECK ("Θ/*/*/*/Φ" == string(parr));
CHECK (NULL == parr[0]);
CHECK (NULL == parr[1]);
CHECK ("Θ" == parr[2]);
CHECK ("*" == parr[3]);
CHECK ("*" == parr[4]);
CHECK ("*" == parr[5]);
CHECK ("Φ" == parr[6]);
VERIFY_ERROR (INDEX_BOUNDS, parr[7]);
VERIFY_ERROR (INDEX_BOUNDS, parr[8]);
}
void
verify_iteration()
{
PathArray parr;
CHECK (isnil (parr));
// path is iterable
CHECK ("" == join(parr));
parr = PathArray{"Γ","Δ","Θ","Ξ","Σ","Ψ","Φ","Ω"};
CHECK (8 == parr.size());
// path is iterable
CHECK ("ΓΔΘΞΣΨΦΩ" == join(parr,""));
// iteration matches index order
uint i=0;
for (PathArray::iterator ii = parr.begin(); ii; ++ii, ++i)
CHECK (parr[i] == *ii);
CHECK (8 == i);
// path information is automatically trimmed and filled
parr = PathArray{nullptr,nullptr,"Θ",nullptr,nullptr,nullptr,"Φ"};
CHECK (7 == parr.size());
CHECK ("Θ***Φ" == join(parr,""));
parr = PathArray{nullptr,"Δ",nullptr,"Ξ",nullptr,nullptr,"Φ"};
CHECK (4 == parr.size());
CHECK ("Δ*Ξ" == join(parr,""));
parr = PathArray{nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,"Ω",nullptr};
CHECK (16 == parr.size());
CHECK ("Ω" == join(parr,""));
// index numbering starts at absolute root
CHECK ("Ω" == *parr.begin());
CHECK (nullptr == parr[0]);
CHECK ("Ω" == parr[15]);
VERIFY_ERROR (INDEX_BOUNDS, parr[16]);
}
void
verify_comparisons()
{
UNIMPLEMENTED ("verify comparison of UI coordinates");
}
};
/** Register this test class... */
LAUNCHER (PathArray_test, "unit gui");
}} // namespace lib::test