blob: 39add79a527cae957db8bc483ec02036337987d7 [file] [log] [blame]
#ifndef UIMA_LISTFS_HPP
#define UIMA_LISTFS_HPP
/** \file listfs.hpp .
-----------------------------------------------------------------------------
* 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.
-----------------------------------------------------------------------------
\brief Contains the family of ListFS classes (IntListFS, FloatListFS etc.)
Description:
-----------------------------------------------------------------------------
-------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------- */
/* Include dependencies */
/* ----------------------------------------------------------------------- */
#include "uima/pragmas.hpp"
#include "uima/lowlevel_typedefs.hpp"
#include "uima/typesystem.hpp"
#include "uima/exceptions.hpp"
#include "uima/featurestructure.hpp"
#include "uima/internal_typeshortcuts.hpp"
#include "unicode/utf.h"
/* ----------------------------------------------------------------------- */
/* Constants */
/* ----------------------------------------------------------------------- */
/* ----------------------------------------------------------------------- */
/* Forward declarations */
/* ----------------------------------------------------------------------- */
namespace uima {
class CAS;
namespace internal {
class FSSystem;
}
}
/* ----------------------------------------------------------------------- */
/* Types / Classes */
/* ----------------------------------------------------------------------- */
namespace uima {
// exceptions
UIMA_EXC_CLASSDECLARE(FSIsNotListException, CASException);
UIMA_EXC_CLASSDECLARE(ListIsEmptyException, CASException);
UIMA_EXC_CLASSDECLARE(ListIsCircularException, CASException);
} // namespace uima
/* ----------------------------------------------------------------------- */
/* BasicListFS */
/* ----------------------------------------------------------------------- */
namespace uima {
/// @if internal
template< class T,
const uima::lowlevel::TyFSType LIST_TYPE,
const uima::lowlevel::TyFSType ELIST_TYPE,
const uima::lowlevel::TyFSType NELIST_TYPE,
const uima::lowlevel::TyFSFeature HEAD_FEATURE,
const uima::lowlevel::TyFSFeature TAIL_FEATURE >
/// @endif internal
/**
* A on object representing a list of elements from the CAS.
* (e.g. they are of type empty list or of type non-empty list).
* An element can be either a FeatureStructure or a float or an int or a
* string. For each such element type there is a sub-class of BasicListFS
* implementing this template interface with type specific methods.
* ListFS, IntListFS, FloatListFS, StringListFS.
*
* All get methods may throw an <code>InvalidFSObjectException</code> if the
* feature structure object is not valid.
*
* Creating a list can be done like this:
@code
// store elements of a vector of strings in a list feature
FeatureStructure fsNewString; // re-used for each new string
StringListFS fsNewList = tcas.createListFS(); // create an empty list
// build up a fs list from our vector
for (size_t i = 0; i < vecStrings.size(); ++i) {
// create a string feature structure
fsNewList.addLast(vecStrings[i]);
}
// now that the list is complete, set the feature value to the list
fsWithListFeature.setFSValue(fListFeature, fsNewList);
@endcode
* Accessing a list can be done like this:
@code
// check if we need to touch our element
if (fsWithListFeature.hasListElements(fListFeature) ) {
// get list
StringListFS fsList = fsWithListFeature.getStringListFSValue(fListFeature);
// iterate list
while (!fsList.isEmpty()) {
cout << fsList.getHead() << " "; // print the string
fsList.moveToNext();
}
}
@endcode
*
* The example uses StringListFS to show the usage of the interfaces with
* strings. Usage of FeatureStructure, int or float values is analogous.
*
* @see ListFS
* @see IntListFS
* @see FloatListFS
* @see StringListFS
*/
class UIMA_LINK_IMPORTSPEC BasicListFS : public FeatureStructure {
friend class CAS;
friend class FeatureStructure;
protected:
/// @if internal
void checkList(lowlevel::TyFS tyFS, TyMessageId tyContext) const;
void checkNEList(lowlevel::TyFS tyFS, TyMessageId tyContext) const;
void checkCircularity(lowlevel::TyFS tyFS1, lowlevel::TyFS tyFS2, TyMessageId tyContext) const;
lowlevel::TyFS getLastListElement(lowlevel::TyFS tyListFS, size_t & rOutSize) const;
lowlevel::TyFS addLastLowlevel(lowlevel::TyFS tyListFS, T tyNewElement);
void appendLowlevel(lowlevel::TyFS tyListFS1, lowlevel::TyFS tyListFS2);
BasicListFS(lowlevel::TyFS anFS, uima::CAS&, bool bDoChecks = true);
/// @endif internal
public:
typedef T HeadType;
/**
* Default CTOR: Creates an invalid BasicListFS (use CAS::createListFS() instead)
*/
BasicListFS();
/**
* Upgrade/Conversion CTOR: Creates an BasicListFS from an existing FeatureStructure.
* fs must be of type List.
*
* @throws FSIsNotListException
*/
explicit BasicListFS( FeatureStructure const & fs );
/**
* Return true if this element is not valid or of type empty list.
* @throws InvalidFSObjectException
*/
bool isEmpty() const;
/**
* Get the value of the head feature of this list element.
* @throws InvalidFSObjectException
* @throws ListIsEmptyException
*/
T getHead() const;
/**
* Set the value of the head feature of this list element.
* @throws InvalidFSObjectException
* @throws ListIsEmptyException
*/
void setHead( T const & fs );
/**
* Get the value of the tail feature of this list element.
* @throws InvalidFSObjectException
* @throws ListIsEmptyException
*/
BasicListFS getTail() const;
/**
* Set the value of the tail feature of this list element.
* @throws InvalidFSObjectException
* @throws ListIsEmptyException
*/
void setTail( BasicListFS fs );
/**
* Get the length of this list.
* @throws InvalidFSObjectException
*/
size_t getLength() const;
/**
* Adds the value fs to the begin of this list.
* addFirst takes constant time with the length of this list
*
* @return The list starting with the newly added element.
* (i.e. the first element of the full list)
*
* @throws InvalidFSObjectException
*/
BasicListFS addFirst( T const & fs );
/**
* Adds the value fs to the end of this list.
* addLast takes linear time with the length of this list
*
* @return The list starting with the newly added element
* (i.e. the last element of the full list)
*
* @throws InvalidFSObjectException
*/
BasicListFS addLast( T const & fs );
/**
* Appends the list l to the end of this list.
* append takes linear time with the length of this list
*
* @return The new list.
*
* @throws InvalidFSObjectException
*/
BasicListFS append( BasicListFS l );
/**
* Appends the list l to the begin of this list.
* prepend takes linear time with the length of list <code>l</code>
*
* @return The new list.
*
* @throws InvalidFSObjectException
*/
BasicListFS prepend( BasicListFS l );
/**
* Advance this list element to the next element in the list.
* Equivalent to <code>this = this.getTailFS();</code>
* Assumes that the list is not empty.
*
* @throws InvalidFSObjectException
* @throws ListIsEmptyException
*/
void moveToNext();
/**
* Removes the first occurrence of element from this list.
*
* @return The singleton list containing the removed element.
*
* @throws InvalidFSObjectException
*/
BasicListFS removeElement( T const & element);
/// @if internal
/**
* Check if the list-value for the feature f on feature structure fs
* has any elements.
* Conceptually this is equivalent to
* <code>!fs.getListFSValue(f).isEmpty()</code>
* But unlike getListFSValue() hasListElements() will not touch the
* feature value for f.
*
* @param fs The feature structure on which to check the value for f
* @param f The feature to check (must be of type list)
*
* @throws InvalidFSObjectException
* @throws InvalidFSFeatureObjectException
* @throws FeatureNotAppropriateException
* @throws FSIsNotListException
*/
static bool hasListElements(FeatureStructure fs, Feature const & f);
/**
* Return feature structure of type list stored at feature fList.
* The return value is guaranteed to be a properly terminated list.
* If the feature value for f is untouched a properly terminated list
* will be created on the fly.
*
* @param fList The feature referencing the list to return.
* fList must be valid.
* fList must be appropriate for this feature strucutre.
* fList must be subsumed by type list.
*
* @throws InvalidFSObjectException
* @throws InvalidFSFeatureObjectException
* @throws FeatureNotAppropriateException
* @throws FSIsNotListException
*/
static BasicListFS getListFSValue(FeatureStructure const & fs, Feature const & fList);
/**
* create a feature structure of type empty list (list length is zero)
* @param bIsPermanent indicate if the data should be permanent,
* i.e., has a lifetime longer than the document
*/
static BasicListFS createListFS( CAS & cas, bool bIsPermanent = false );
/**
* create a feature structure of type non-empty list (list length is 1)
* @param fsHead the feature structure to be made the head of the new list.
* cas.createListFS(f).getHead() == f
* @param bIsPermanent indicate if the data should be permanent,
* i.e., has a lifetime longer than the document
*/
static BasicListFS createListFS( CAS & cas, T const & head, bool bIsPermanent = false );
/// @endif internal
}
; // class BasicListFS
typedef BasicListFS< FeatureStructure, internal::gs_tyFSListType, internal::gs_tyEListType, internal::gs_tyNEListType, internal::gs_tyHeadFeature, internal::gs_tyTailFeature > BasicFSListFS;
/**
* A ListFS object implements a list of FeatureStructure objects
* It is derived from the BasicListFS template interface so all
* interesting member functions are derived from BasicListFS.
* @see BasicListFS
* @see IntListFS
* @see FloatListFS
* @see StringListFS
*/
class UIMA_LINK_IMPORTSPEC ListFS : public BasicFSListFS {
/// @if internal
friend class CAS;
friend class FeatureStructure;
protected:
ListFS(lowlevel::TyFS anFS, uima::CAS & cas, bool bDoChecks = true) :
BasicFSListFS(anFS, cas, bDoChecks) {}
public:
/**
* Default CTOR: Creates an invalid ListFS (use CAS::createListFS() instead)
*/
ListFS() :
BasicFSListFS() {}
/**
* Upgrade/Conversion CTOR: Creates an ListFS from an existing FeatureStructure.
* fs must be of type List.
*
* @throws FSIsNotListException
*/
explicit ListFS( FeatureStructure const & fs ) :
BasicFSListFS(fs) {}
/**
* Upgrade/Conversion CTOR: Creates an ListFS from an existing BasicListFS.
*/
ListFS( BasicFSListFS const & fs ) :
BasicFSListFS(fs) {}
/// @endif internal
};
typedef BasicListFS< float, internal::gs_tyFloatListType, internal::gs_tyEFloatListType, internal::gs_tyNEFloatListType, internal::gs_tyFloatHeadFeature, internal::gs_tyFloatTailFeature > BasicFloatListFS;
/**
* A FloatListFS object implements a list of float values.
* It is derived from the BasicListFS template interface so all
* interesting member functions are derived from BasicListFS.
* @see BasicListFS
* @see ListFS
* @see IntListFS
* @see StringListFS
*/
class UIMA_LINK_IMPORTSPEC FloatListFS : public BasicFloatListFS {
/// @if internal
friend class CAS;
friend class FeatureStructure;
protected:
FloatListFS(lowlevel::TyFS anFS, uima::CAS & cas, bool bDoChecks = true) :
BasicFloatListFS(anFS, cas, bDoChecks) {}
public:
/**
* Default CTOR: Creates an invalid ListFS (use CAS::createListFS() instead)
*/
FloatListFS() :
BasicFloatListFS() {}
/**
* Upgrade/Conversion CTOR: Creates an ListFS from an existing FeatureStructure.
* fs must be of type List.
*
* @throws FSIsNotListException
*/
explicit FloatListFS( FeatureStructure const & fs ) :
BasicFloatListFS(fs) {}
/**
* Upgrade/Conversion CTOR: Creates an ListFS from an existing BasicListFS.
*/
FloatListFS( BasicFloatListFS const & fs ) :
BasicFloatListFS(fs) {}
/// @endif internal
};
typedef BasicListFS< int, internal::gs_tyIntListType, internal::gs_tyEIntListType, internal::gs_tyNEIntListType, internal::gs_tyIntHeadFeature, internal::gs_tyIntTailFeature > BasicIntListFS;
/**
* A IntListFS object implements a list of int values.
* It is derived from the BasicListFS template interface so all
* interesting member functions are derived from BasicListFS.
* @see BasicListFS
* @see ListFS
* @see FloatListFS
* @see StringListFS
*/
class UIMA_LINK_IMPORTSPEC IntListFS : public BasicIntListFS {
/// @if internal
friend class CAS;
friend class FeatureStructure;
protected:
IntListFS(lowlevel::TyFS anFS, uima::CAS & cas, bool bDoChecks = true) :
BasicIntListFS(anFS, cas, bDoChecks) {}
public:
/**
* Default CTOR: Creates an invalid ListFS (use CAS::createListFS() instead)
*/
IntListFS() :
BasicIntListFS() {}
/**
* Upgrade/Conversion CTOR: Creates an ListFS from an existing FeatureStructure.
* fs must be of type List.
*
* @throws FSIsNotListException
*/
explicit IntListFS( FeatureStructure const & fs ) :
BasicIntListFS(fs) {}
/**
* Upgrade/Conversion CTOR: Creates an ListFS from an existing BasicListFS.
*/
IntListFS( BasicIntListFS const & fs ) :
BasicIntListFS(fs) {}
/// @endif internal
};
typedef BasicListFS< UnicodeStringRef, internal::gs_tyStringListType, internal::gs_tyEStringListType, internal::gs_tyNEStringListType, internal::gs_tyStringHeadFeature, internal::gs_tyStringTailFeature > BasicStringListFS;
/**
* A StringListFS object implements a list of string values.
* It is derived from the BasicListFS template interface so all
* interesting member functions are derived from BasicListFS.
* @see BasicListFS
* @see ListFS
* @see IntListFS
* @see FloatListFS
*/
class UIMA_LINK_IMPORTSPEC StringListFS : public BasicStringListFS {
/// @if internal
friend class CAS;
friend class FeatureStructure;
protected:
StringListFS(lowlevel::TyFS anFS, uima::CAS & cas, bool bDoChecks = true) :
BasicStringListFS(anFS, cas, bDoChecks) {}
public:
/**
* Default CTOR: Creates an invalid ListFS (use CAS::createListFS() instead)
*/
StringListFS() :
BasicStringListFS() {}
/**
* Upgrade/Conversion CTOR: Creates an ListFS from an existing FeatureStructure.
* fs must be of type List.
*
* @throws FSIsNotListException
*/
explicit StringListFS( FeatureStructure const & fs ) :
BasicStringListFS(fs) {}
/**
* Upgrade/Conversion CTOR: Creates an ListFS from an existing BasicListFS.
*/
StringListFS( BasicStringListFS const & fs ) :
BasicStringListFS(fs) {}
/// @endif internal
};
} // namespace uima
#endif
/* <EOF> */