Files
secondo/Algebras/Raster2/stype.h
2026-01-23 17:03:45 +08:00

965 lines
30 KiB
C++

/*
----
This file is part of SECONDO.
Copyright (C) 2011, University in Hagen, Department of Computer Science,
Database Systems for New Applications.
SECONDO 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.
SECONDO 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 SECONDO; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
----
*/
#ifndef RASTER2_STYPE_H
#define RASTER2_STYPE_H
/*
1 Overview
This file defines a class template ~stype$<$T, Helper$>$~ for spatial raster
data. The template arguments are
* *T* -- the type of data that is stored in the raster cells,
* *Helper* -- a helper class that maps general functionality on objects of
type ~T~ to their concrete implementation within Secondo.
*/
#include <algorithm>
#include <cassert>
#include <stdexcept>
#include <vector>
#include <string>
#include <utility>
#include <SecondoSMI.h>
#include <StandardTypes.h>
#include <Algebras/RTree/RTreeAlgebra.h>
#include <LogMsg.h>
#include <Algebras/FText/FTextAlgebra.h>
#include <Stream.h>
#include "grid2.h"
#include "Defines.h"
#include "RasterStorage.h"
#include "./Import/Import.h"
#include "util/noncopyable.h"
#include "util/parse_error.h"
namespace raster2
{
/*
2 Class Template ~stype\_helper~
The class template ~stype\_helper~ defines the requirements of the ~Helper~
template argument to the ~stype$<$T, Helper$>$~ class template.
*/
template <class T>
struct stype_helper
{
typedef T implementation_type;
typedef T wrapper_type;
static std::string name();
static bool check(const NList& nl);
static T parse(const NList& nl);
static NList print(const T& i);
static bool isUndefined(const T& t);
static T getUndefined();
static std::string BasicType();
static wrapper_type wrap(const T& i);
static T unwrap(const wrapper_type& i);
};
/*
In this class template,
* ~wrapper\_type~ -- is the data type that is used by Secondo to represent
values of type ~T~,
* ~name~ -- is the name under which the data type ~stype$<$T, Helper$>$~
should be known to Secondo, i. e. the return value of
~stype$<$T, Helper$>$::BasicType()~,
* ~check(const NList\& nl)~ tests whether an NList object represents a value
of type ~T~,
* ~parse(const NList\& nl)~ -- parses an NList to yield an object of type ~T~,
* ~getUndefined()~ -- retrieves the undefined value of type ~T~,
* ~checkUndefined(const T\&)~ -- tests whether the given value is undefined.
The ~wrapper\_type~ must provide two constructors:
* ~wrapper\_type(const T\& v)~ or ~wrapper\_type(T v)~ -- must create a
defined objects with value v,
* ~wrapper\_type(bool b)~ -- must create an uninitialized object that is
defined iff ~b == true~.
Examples of wrapper types are CcInt, CcReal.
3 Definition of the ~stype$<$T, Helper$>$~ Class Template
*/
template <typename T, typename Helper = stype_helper<T> > class stype;
template <typename T, typename Helper>
void swap(stype<T, Helper>&, stype<T, Helper>&);
template <typename T, typename Helper>
class stype : util::noncopyable
{
/*
~stype$<$T, Helper$>$~ makes heavy use of other classes that are implemented as
templates. To ease usage of these classes, they are typedefed to more convenient
names.
*/
public:
typedef stype<T, Helper> this_type;
typedef T cell_type;
typedef typename Helper::wrapper_type wrapper_type;
typedef RasterStorage<T, 2, Helper::isUndefined> storage_type;
typedef RasterIndex<2> index_type;
typedef RasterStorageIterator<T, 2, Helper::isUndefined> iter_type;
typedef RasterStorageRegionIterator<T, 2, Helper::isUndefined>
riter_type;
typedef typename Helper::moving_type moving_type;
typedef typename Helper::unit_type unit_type;
typedef grid2 grid_type;
static bool isUndefined(const T& t) {
return Helper::isUndefined(t);
}
static wrapper_type wrap(const T& t) {
return Helper::wrap(t);
}
static T unwrap(const wrapper_type& w) {
return Helper::unwrap(w);
}
/*
~stype$<$T, Helper$>$~ objects can either be constructed by passing two
~SmiFileId~ objects, or by passing a pointer to a ~RasterStorage~ object. In the
second case, ~stype$<$T, Helper$>$~ will take ownership of the object and
release it by calling delete on it in the destructor.
*/
public:
stype();
stype(const grid2&, SmiFileId, SmiFileId, const T&, const T&);
~stype();
riter_type begin_regions() const;
riter_type end_regions() const;
riter_type iterate_regions(const index_type& from,
const index_type& to) const;
void set(const index_type& i, const T& value);
T get(const index_type& i) const;
void setCacheSize(size_t size);
void flushCache();
/*
~stype$<$T, Helper$>$~ provides some convenience functions that are used by
Secondo operators.
*/
public:
void destroy();
storage_type& getStorage();
T atlocation(double x, double y) const;
void setatlocation(double x, double y, const T& value);
this_type* atrange(const Rectangle<2>& rect) const;
Rect bbox() const;
T getMinimum() const;
T getMaximum() const;
grid2 getGrid() const;
void setGrid(const grid2& rGrid);
void clear();
void setDefined(const bool defined);
bool isDefined() const;
int importHgtFile(const char *currentHGTFile,
RasterData *HGTRasterData,
bool init, storage_type& rs);
bool checkHGTConsistency(storage_type& rs,
long xOffset,
long yOffset, int extend,
RasterData *HGTRasterData,
int16_t* data);
int importEsriGridFile(RasterData *HGTRasterData);
void processEsriGridByRTileType(
std::ifstream *esriGridDataFile,
RasterData *esriRasterData,
const uint32_t tileColIdx,
const uint32_t tileRowIdx,
const size_t maxRasterIdxY,
const uint32_t cellColCount,
const uint32_t cellRowCount,
const uint32_t tileLimitCount);
void processConstantBlockData(
std::ifstream *dataFile,
RasterData *esriRasterData,
const uint32_t tileColIdx,
const uint32_t tileRowIdx,
const size_t maxRasterIdxY,
const uint32_t cellColCount,
const uint32_t cellRowCount,
const uint8_t rMinSize);
void processEsriTilePixelValueData(
std::ifstream *dataFile,
const uint8_t *rTileType,
RasterData *esriRasterData,
const uint32_t tileColIdx,
const uint32_t tileRowIdx,
const size_t maxRasterIdxY,
const uint32_t cellColCount,
const uint32_t cellRowCount,
const uint32_t tileLimitCount,
const uint8_t rMinSize);
void processEsriTileLiteralRunsData(
std::ifstream *dataFile,
RasterData *esriRasterData,
const uint32_t tileColIdx,
const uint32_t tileRowIdx,
const size_t maxRasterIdxY,
const uint32_t cellColCount,
const uint32_t cellRowCount,
const uint32_t tileLimitCount,
const uint8_t rMinSize);
void processEsriTile16BitLiteralRunsData(
std::ifstream *dataFile,
RasterData *esriRasterData,
const uint32_t tileColIdx,
const uint32_t tileRowIdx,
const size_t maxRasterIdxY,
const uint32_t cellColCount,
const uint32_t cellRowCount,
const uint32_t tileLimitCount,
const uint8_t rMinSize);
void processEsriTileRMinRunsData(
std::ifstream *dataFile,
RasterData *esriRasterData,
const uint32_t tileColIdx,
const uint32_t tileRowIdx,
const size_t maxRasterIdxY,
const uint32_t cellColCount,
const uint32_t cellRowCount,
const uint32_t tileLimitCount,
const uint8_t rMinSize);
void processEsriTileCountLengthData(
std::ifstream *dataFile,
const uint8_t *rTileType,
RasterData *esriRasterData,
const uint32_t tileColIdx,
const uint32_t tileRowIdx,
const size_t maxRasterIdxY,
const uint32_t cellColCount,
const uint32_t cellRowCount,
const uint32_t tileLimitCount,
const uint8_t rMinSize);
void processEsriTileRMin1BitData(
std::ifstream *dataFile,
RasterData *esriRasterData,
const uint32_t tileColIdx,
const uint32_t tileRowIdx,
const size_t maxRasterIdxY,
const uint32_t cellColCount,
const uint32_t cellRowCount,
const uint32_t tileLimitCount,
const uint8_t rMinSize);
void processEsriTileRMinCCITTRLEData(
std::ifstream *dataFile,
RasterData *esriRasterData,
const uint32_t tileColIdx,
const uint32_t tileRowIdx,
const size_t maxRasterIdxY,
const uint32_t cellColCount,
const uint32_t cellRowCount,
const uint32_t tileLimitCount,
const uint16_t rTileSize,
const uint8_t rMinSize);
int importEsriRasterFile(
const char *currentEsriFile,
RasterData *EsriRasterData,
bool init, storage_type& rs);
/*
Internally, an ~stype$<$T, Helper$>$~ object consists of the grid definition and
~RasterStorage~ object for convenient access to the ~SmiFile~s. Additional
member variables are provided for convenience.
*/
private:
friend void swap<T, Helper>(this_type&, this_type&);
bool tmp;
grid2 grid;
T minimum;
T maximum;
storage_type* storage;
bool defined;
public:
static TypeConstructor getTypeConstructor();
static std::string BasicType();
static bool checkType(const ListExpr e);
static bool Open(SmiRecord& valueRecord, size_t& offset,
const ListExpr typeInfo, Word& value );
static bool Save(SmiRecord& valueRecord, size_t& offset,
const ListExpr typeInfo, Word& w );
static Word In(const ListExpr typeInfo, const ListExpr instance,
const int errorPos, ListExpr& errorInfo,
bool& correct);
static ListExpr Out(ListExpr typeInfo, Word value);
static Word Create(const ListExpr typeInfo);
static void Delete(const ListExpr typeInfo, Word& w);
static void Close(const ListExpr typeInfo, Word& w);
static Word Clone(const ListExpr typeInfo, const Word& w);
static bool KindCheck(ListExpr type, ListExpr& errorInfo);
static void* Cast(void* placement);
static int SizeOfObj();
static ListExpr Property();
};
/*
4 Implementation of the ~stype$<$T, Helper$>$~ Class Template
4.1 Construction, Destruction and Initialization
*/
template <typename T, typename Helper>
stype<T, Helper>::stype
(const grid2& g, SmiFileId r, SmiFileId t, const T& min, const T& max)
: tmp(false), grid(g), minimum(min), maximum(max),
storage(new storage_type(Helper::getUndefined(), r, t)),
defined(true)
{
}
template <typename T, typename Helper>
stype<T, Helper>::stype()
: tmp(false), grid(0.0, 0.0, 1.0),
minimum(Helper::getUndefined()),
maximum(Helper::getUndefined()),
storage(new storage_type(Helper::getUndefined())),
defined(true)
{
}
template <typename T, typename Helper>
stype<T, Helper>::~stype() {
if (tmp) {
storage->remove();
}
delete storage;
}
template <typename T, typename Helper>
void stype<T, Helper>::destroy()
{
tmp = true;
}
template <typename T, typename Helper>
typename stype<T, Helper>::riter_type
stype<T, Helper>::begin_regions() const
{
assert(storage != 0);
return storage->begin_regions();
}
template <typename T, typename Helper>
typename stype<T, Helper>::riter_type
stype<T, Helper>::end_regions() const
{
assert(storage != 0);
return storage->end_regions();
}
template <typename T, typename Helper>
typename stype<T, Helper>::riter_type
stype<T, Helper>::iterate_regions(const index_type& from,
const index_type& to) const
{
return storage->iterate_regions(from, to);
}
template <typename T, typename Helper>
void stype<T, Helper>::set(const index_type& i, const T& value) {
assert(storage != 0);
(*storage)[i] = value;
if (Helper::isUndefined(minimum)) {
minimum = value;
} else if (!Helper::isUndefined(value)) {
if (value < minimum) {
minimum = value;
}
}
if (Helper::isUndefined(maximum)) {
maximum = value;
} else if (!Helper::isUndefined(value)) {
if (value > maximum) {
maximum = value;
}
}
}
template <typename T, typename Helper>
T stype<T, Helper>::get(const index_type& i) const {
assert(storage != 0);
return (*storage)[i];
}
template <typename T, typename Helper>
void stype<T, Helper>::setCacheSize(size_t size) {
storage->setCacheSize(size);
}
template <typename T, typename Helper>
void stype<T, Helper>::flushCache() {
storage->flushCache();
}
/*
4.2 Member Functions
*/
template <typename T, typename Helper>
inline RasterStorage<T, 2, Helper::isUndefined>&
stype<T, Helper>::getStorage()
{
assert(storage != 0);
return *storage;
}
template <typename T, typename Helper>
inline T stype<T, Helper>::atlocation(double x, double y) const {
return (*storage)[grid.getIndex(x, y)];
}
template <typename T, typename Helper>
inline void stype<T, Helper>::setatlocation
(double x, double y, const T& value)
{
(*storage)[grid.getIndex(x, y)] = value;
}
template <typename T, typename Helper>
stype<T, Helper>*
stype<T, Helper>::atrange(const Rectangle<2>& rect) const {
this_type* result = new this_type();
result->grid = grid;
index_type rfrom = grid.getIndex(rect.MinD(0), rect.MinD(1));
index_type rto = grid.getIndex(rect.MaxD(0), rect.MaxD(1));
for (riter_type rit = iterate_regions(rfrom, rto),
re = end_regions();
rit != re; ++rit)
{
index_type from = *rit;
index_type to = *rit + riter_type::region_size;
for (index_type i = from; i < to; i.increment(from, to)) {
if ((rect.MinD(0) <=
(i[0] * grid.getLength() + grid.getOriginX()) &&
rect.MaxD(0) >=
(i[0] * grid.getLength() + grid.getOriginX())) &&
(rect.MinD(1) <=
(i[1] * grid.getLength() + grid.getOriginY()) &&
rect.MaxD(1) >=
(i[1] * grid.getLength() + grid.getOriginY())))
result->set(i, get(i));
}
}
return result;
}
template <typename T, typename Helper>
inline Rect stype<T, Helper>::bbox() const {
if(!isDefined()){
return Rect(false);
}
RasterRegion<2> bbox = (*storage).bbox();
double min[2] = {
bbox.Min[0] * grid.getLength() + grid.getOriginX(),
bbox.Min[1] * grid.getLength() + grid.getOriginY()
};
double max[2] = {
bbox.Max[0] * grid.getLength() + grid.getOriginX(),
bbox.Max[1] * grid.getLength() + grid.getOriginY()
};
return Rect(true, min, max);
}
template <typename T, typename Helper>
inline T stype<T, Helper>::getMinimum() const {
if(isDefined()){
return minimum;
} else {
return Helper::getUndefined();
}
};
template <typename T, typename Helper>
inline T stype<T, Helper>::getMaximum() const {
if(isDefined()){
return maximum;
} else {
return Helper::getUndefined();
}
};
template <typename T, typename Helper>
inline grid2 stype<T, Helper>::getGrid() const { return grid; };
template <typename T, typename Helper>
void stype<T, Helper>::setGrid(const grid2& rGrid)
{
grid = rGrid;
}
template <typename T, typename Helper>
void stype<T, Helper>::clear()
{
storage->clear();
minimum = Helper::getUndefined();
maximum = Helper::getUndefined();
defined = true;
}
template <typename T, typename Helper>
void stype<T, Helper>::setDefined(const bool _defined){
if(defined != _defined){
defined = _defined;
if(!defined){
clear();
defined = false;
}
}
}
template <typename T, typename Helper>
bool stype<T, Helper>::isDefined() const{
return defined;
}
/*
4.3 Static Member Functions for use by Secondo
*/
template <typename T, typename Helper>
TypeConstructor stype<T, Helper>::getTypeConstructor() {
TypeConstructor tc_stype(
stype<T, Helper>::BasicType(),
stype<T, Helper>::Property,
stype<T, Helper>::Out,
stype<T, Helper>::In,
0,
0,
stype<T, Helper>::Create,
stype<T, Helper>::Delete,
stype<T, Helper>::Open,
stype<T, Helper>::Save,
stype<T, Helper>::Close,
stype<T, Helper>::Clone,
stype<T, Helper>::Cast,
stype<T, Helper>::SizeOfObj,
stype<T, Helper>::KindCheck);
tc_stype.AssociateKind(Kind::SIMPLE());
return tc_stype;
}
template <typename T, typename Helper>
std::string stype<T, Helper>::BasicType() {
return Helper::name();
}
template <typename T, typename Helper>
bool stype<T, Helper>::checkType(const ListExpr e) {
return listutils::isSymbol(e,BasicType());
}
template <typename T, typename Helper>
bool stype<T, Helper>::Open( SmiRecord& valueRecord, size_t& offset,
const ListExpr typeInfo, Word& value )
{
valueRecord.SetPos(offset);
grid2 grid;
SmiFileId idraster;
SmiFileId idtree;
T minimum;
T maximum;
valueRecord.Read(grid);
valueRecord.Read(idraster);
valueRecord.Read(idtree);
valueRecord.Read(minimum);
valueRecord.Read(maximum);
offset = valueRecord.GetPos();
this_type* p_stype =
new this_type(grid, idraster, idtree, minimum, maximum);
value.setAddr(p_stype);
return true;
}
template <typename T, typename Helper>
bool stype<T, Helper>::Save( SmiRecord& valueRecord, size_t& offset,
const ListExpr typeInfo, Word& value )
{
this_type* p_stype = static_cast<this_type*>(value.addr);
SmiFileId raster = p_stype->storage->getRasterFileId(),
tree = p_stype->storage->getTreeFileId();
valueRecord.SetPos(offset);
valueRecord.Write(p_stype->grid);
valueRecord.Write(raster);
valueRecord.Write(tree);
valueRecord.Write(p_stype->minimum);
valueRecord.Write(p_stype->maximum);
offset = valueRecord.GetPos();
return true;
}
template <typename T, typename Helper>
Word stype<T, Helper>::In(const ListExpr typeInfo, const ListExpr instance,
const int errorPos, ListExpr& errorInfo,
bool& correct )
{
NList nlist(instance);
grid2 grid;
std::pair<int, int> sizes;
this_type* p_stype = new this_type();
if(listutils::isSymbolUndefined(instance)){
p_stype->setDefined(false);
correct = true;
return Word(p_stype);
}
try {
if (nlist.isAtom()) {
throw util::parse_error
("Expected list as first element, got an atom.");
}
NList gridlist = nlist.elem(1);
nlist.rest();
if (gridlist.length() != 3) {
throw util::parse_error
("Type mismatch: list for grid2 is too short or too long.");
}
if (!gridlist.isReal(1)
|| !gridlist.isReal(2)
|| !gridlist.isReal(3))
{
throw util::parse_error(
"Type mismatch: expected 3 reals as grid2 sublist.");
}
if (gridlist.elem(3).realval() <= 0) {
throw util::parse_error(
"The length in a grid2 must be larger than 0.");
}
grid = grid2(
gridlist.elem(1).realval(),
gridlist.elem(2).realval(),
gridlist.elem(3).realval()
);
p_stype->setGrid(grid);
if (!nlist.isEmpty()) {
NList sizelist = nlist.elem(1);
nlist.rest();
if (sizelist.length() != 2) {
throw util::parse_error(
"Type mismatch: list for grid2 is too short.");
}
if ( sizelist.isInt(1)
&& sizelist.isInt(2)
&& sizelist.elem(1).intval() > 0
&& sizelist.elem(2).intval() > 0)
{
sizes.first = sizelist.elem(1).intval();
sizes.second = sizelist.elem(2).intval();
} else {
throw util::parse_error("Type mismatch: "
"partial grid size must contain two positive integers.");
}
}
while (!nlist.isEmpty()) {
index_type root;
NList pagelist = nlist.first();
nlist.rest();
if (pagelist.length() != 3) {
throw util::parse_error("Type mismatch: "
"partial grid content must contain three elements.");
}
if (pagelist.isInt(1) && pagelist.isInt(2)) {
root[0] = pagelist.elem(1).intval();
root[1] = pagelist.elem(2).intval();
} else {
throw util::parse_error("Type mismatch: "
"partial grid content must start with two integers.");
}
pagelist.rest();
pagelist.rest();
NList valuelist = pagelist.first();
if ( valuelist.length()
!= Cardinal(sizes.first) * Cardinal(sizes.second))
{
throw util::parse_error("Type mismatch: "
"list for partial grid values is too short or too long.");
}
for (int r = 0; r < sizes.second; ++r) {
for (int c = 0; c < sizes.first; ++c) {
T value;
int i = r * sizes.first + c + 1;
if (valuelist.elem(i).isSymbol(Symbol::UNDEFINED())) {
value = Helper::getUndefined();
} else if (Helper::check(valuelist.elem(i))) {
value = Helper::parse(valuelist.elem(i));
} else {
throw util::parse_error("Type mismatch: "
"list value in partial grid has wrong type.");
}
index_type index((int[]){root[0] + c, root[1] + r});
p_stype->set(index, value);
}
}
}
} catch (util::parse_error& e) {
p_stype->destroy();
delete p_stype;
cmsg.inFunError(e.what());
correct = false;
return Word();
}
correct = true;
return SetWord(p_stype);
}
template <typename T, typename Helper>
ListExpr stype<T, Helper>::Out(ListExpr typeInfo, Word value)
{
this_type* p_stype = static_cast<this_type*>(value.addr);
if(!p_stype->isDefined()){
cout << "undefined stype " << endl;
return nl->SymbolAtom(Symbol::UNDEFINED());
}
NList result;
NList gridlist;
gridlist.append(p_stype->grid.getOriginX());
gridlist.append(p_stype->grid.getOriginY());
gridlist.append(p_stype->grid.getLength());
result.append(gridlist);
NList tilesizelist;
const index_type& size = riter_type::region_size;
index_type index;
T element;
storage_type& storage = p_stype->getStorage();
RasterRegion<2> bb = storage.bbox();
index_type sz = bb.Max - bb.Min;
if (sz[0] <= size[0] && sz[1] <= size[1]) {
tilesizelist.append(1);
tilesizelist.append(1);
result.append(tilesizelist);
for (iter_type it = storage.begin(),
e = storage.end();
it != e; ++it)
{
element = *it;
NList partiallist;
partiallist.append(it.getIndex()[0]);
partiallist.append(it.getIndex()[1]);
NList valuelist;
valuelist.append(Helper::print(element));
partiallist.append(valuelist);
result.append(partiallist);
}
} else {
tilesizelist.append(size[0]);
tilesizelist.append(size[1]);
result.append(tilesizelist);
for (riter_type rit = storage.begin_regions(),
re = storage.end_regions();
rit != re; ++rit)
{
NList partiallist;
partiallist.append((*rit)[0]);
partiallist.append((*rit)[1]);
NList valuelist;
for (int r = 0; r < size[0]; ++r) {
for (int c = 0; c < size[1]; ++c) {
index = *rit + index_type((int[]){c, r});
element = storage[index];
valuelist.append(Helper::print(element));
}
}
partiallist.append(valuelist);
result.append(partiallist);
}
}
return result.listExpr();
}
template <typename T, typename Helper>
Word stype<T, Helper>::Create(const ListExpr typeInfo) {
this_type* p_stype = new this_type();
return SetWord(p_stype);
}
template <typename T, typename Helper>
void stype<T, Helper>::Delete(const ListExpr typeInfo, Word& w) {
this_type* p_stype = static_cast<this_type*>(w.addr);
p_stype->destroy();
delete p_stype;
w.addr = 0;
}
template <typename T, typename Helper>
void stype<T, Helper>::Close(const ListExpr typeInfo, Word& w) {
delete static_cast<this_type*>(w.addr);
w.addr = 0;
}
template <typename T, typename Helper>
Word stype<T, Helper>::Clone(const ListExpr typeInfo, const Word& w)
{
this_type* source = static_cast<this_type*>(w.addr);
this_type* clone = new this_type();
clone->setGrid(source->getGrid());
for (riter_type rit = source->storage->begin_regions(),
re = source->storage->end_regions();
rit != re; ++rit)
{
index_type from = *rit;
index_type to = from + storage_type::region_size;
for (index_type i = from,
e = to;
i < e; i.increment(from, to))
{
clone->set(i, (*source->storage)[i]);
}
}
return SetWord(clone);
}
template <typename T, typename Helper>
bool stype<T, Helper>::KindCheck(ListExpr type, ListExpr& errorInfo) {
return NList(type).isSymbol(stype<T, Helper>::BasicType());
}
template <typename T, typename Helper>
void* stype<T, Helper>::Cast(void* placement) {
return new(placement) this_type;
}
template <typename T, typename Helper>
int stype<T, Helper>::SizeOfObj() {
return sizeof(this_type);
}
template <typename T, typename Helper>
ListExpr stype<T, Helper>::Property() {
NList property;
NList names;
names.append(NList(std::string("Signature"), true));
names.append(NList(std::string("Example Type List"), true));
names.append(NList(std::string("ListRep"), true));
names.append(NList(std::string("Example List"), true));
names.append(NList(std::string("Remarks"), true));
NList values;
values.append(NList(std::string("-> DATA"), true));
values.append(NList(BasicType(), true));
values.append(NList(
std::string(
"((x y l) (szx szy) ((ix iy (v*)))*)"),
true));
values.append(NList(
std::string(
"((0.0 0.0 1.0) (2 2) ((-32 -32 (1 2 3 4))))"),
true));
values.append(NList(std::string(""), true));
property = NList(names, values);
return property.listExpr();
}
template <typename T, typename Helper>
void swap(raster2::stype<T, Helper>& a, raster2::stype<T, Helper>& b)
{
std::swap(a.tmp, b.tmp);
std::swap(a.grid, b.grid);
std::swap(a.minimum, b.minimum);
std::swap(a.maximum, b.maximum);
std::swap(a.storage, b.storage);
}
}
#endif /* #ifndef RASTER2_STYPE_H */