UI-Coordinates: extract PathArray base abstraction into a library class
This commit is contained in:
parent
4082526ec6
commit
5e1c25aaf5
4 changed files with 351 additions and 82 deletions
|
|
@ -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
165
src/lib/path-array.hpp
Normal 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*/
|
||||
|
|
@ -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
|
||||
|
|
|
|||
177
tests/library/path-array-test.cpp
Normal file
177
tests/library/path-array-test.cpp
Normal 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
|
||||
Loading…
Reference in a new issue