Files
secondo/Algebras/ChessB/ValueMapping.hpp
2026-01-23 17:03:45 +08:00

399 lines
12 KiB
C++

/*
Template Functions hiding the Secondo Interface for Value Mappings
*/
#ifndef SECONDO_VALUE_MAPPING_HPP
#define SECONDO_VALUE_MAPPING_HPP
#include <boost/assert.hpp>
#include "AlgebraTypes.h"
#include "StandardTypes.h"
#include "QueryProcessor.h"
#include "Algebras/Relation-C++/RelationAlgebra.h"
#include "Attribute.h"
#include "StreamIterator.hpp"
//-----------------------------------------------------------------------------
// Result value conversion to secondo type
Attribute* result_value( bool b ){ return new CcBool( true, b ); }
Attribute* result_value( std::string s ){ return new CcString( true, s ); }
Attribute* result_value( int i ){ return new CcInt( true, i ); }
Attribute* result_value( double d ){ return new CcReal( true, d ); }
Tuple* result_value( Tuple* t ) { return t; }
template< typename T > Attribute* result_value( T attr )
{ return static_cast<Attribute*>( attr ); }
void setResultValue(void* resAddr, const bool b){
(static_cast<CcBool*>(resAddr))->Set(true, b);
}
void setResultValue(void* resAddr, const std::string& s){
(static_cast<CcString*>(resAddr))->Set(true,s);
}
void setResultValue(void* resAddr, const int i){
(static_cast<CcInt*>(resAddr))->Set(true, i);
}
void setResultValue(void* resAddr, const double d){
(static_cast<CcReal*>(resAddr))->Set(true, d);
}
void setResultValue(void* resAddr, const Attribute* a){
(static_cast<Attribute*>(resAddr))->CopyFrom(a);
}
void setResultValue(void*& resAddr, Tuple* t){
resAddr = t;
}
template<typename T> void setResultValue(void* resAddr, T attr){
(static_cast<T>(resAddr))->CopyFrom(attr);
}
void delPointer(int i) { }
void delPointer(std::string s){}
void delPointer(double d){ }
void delPointer(bool b){ }
void delPointer(Attribute*& a){
a->DeleteIfAllowed();
a=0;
}
void delPointer(Tuple*& t){
t->DeleteIfAllowed();
t=0;
}
template<typename T>
void delPointer(T*& p){
p->DeleteIfAllowed();
p = 0;
}
void* on_open_arg( void* arg, void* ){ return arg; }
void* on_request_arg( void* arg, void* ){ return arg; }
// the next argument conversion is needed for forall and exists
void* on_open_arg( void* arg, void** ){ return arg; }
void* on_request_arg( void* arg, void** ){ return arg; }
// default behavior, cast from Attibute to an Attibute-derived type
template< typename T > T& on_open_arg( void* arg, T* ){
return *static_cast<T*>( arg );
}
template< typename T > T& on_request_arg( void* arg, T* ){
return *static_cast<T*>( arg );
}
template< typename T > void on_close_arg( void* arg, T* ){}
// initialize StreamIterator
template< typename T >
StreamIterator<T> on_open_arg( void* arg, StreamIterator<T>* )
{
qp->Open( arg );
return StreamIterator<T>(0);
}
template< typename T >
StreamIterator<T> on_request_arg( void* arg, StreamIterator<T>* )
{
return StreamIterator<T>( arg );
}
template< typename T > void on_close_arg( void* arg, StreamIterator<T>* )
{
qp->Close( arg );
}
//-----------------------------------------------------------------------------
#include "QueryProcessor.h"
template< typename ARG, typename R >
struct Function
{
Function( void* arg ) : handle_(arg){}
R operator()( const ARG& arg ) const
{
BOOST_ASSERT( handle_ != 0 && "Function handle is null!" );
Word value;
( *qp->Argument(handle_) )[0].addr = arg;
qp->Request( handle_, value );
return static_cast<R*>( value.addr );
}
private:
void* handle_;
};
//-----------------------------------------------------------------------------
// initialize Function
template< typename A, typename R >
Function< A, R > on_open_arg( void* arg, Function< A, R >* ) {
return Function< A, R >( arg );
}
template< typename A, typename R >
Function< A, R > on_request_arg( void* arg, Function< A, R >* ) {
return Function< A, R >( arg );
}
template< typename A, typename R >
void on_close_arg( void* arg, Function< A, R >* ){}
//-----------------------------------------------------------------------------
// Value mapping functions
template< typename O >
int unary_value_map( Word* args, Word& result, int msg, Word&, Supplier s )
{
typedef typename O::argument_type A;
typedef typename O::result_type R;
result = qp->ResultStorage( s );
on_open_arg( args[0].addr, (A*)0 );
// if ( static_cast<Attribute*>( args[0].addr )->IsDefined() )
// {
try
{
// result.addr = result_value( O()
// ( on_request_arg( args[0].addr, (A*)0 ) ) );
R res = O()(on_request_arg(args[0].addr, (A*)0));
setResultValue(result.addr, res);
delPointer(res);
return 0;
}
catch( const std::exception& e ) {
std::cerr << e.what() << endl;
}
// }
on_close_arg( args[0].addr, (A*)0 );
// static_cast<Attribute*>(result.addr)->SetDefined( false );
return 0;
}
template< typename O >
int binary_value_map( Word* args, Word& result, int, Word&, Supplier s )
{
typedef typename O::first_argument_type A1;
typedef typename O::second_argument_type A2;
typedef typename O::result_type R;
result = qp->ResultStorage( s );
on_open_arg( args[0].addr, (A1*)0 );
on_open_arg( args[1].addr, (A2*)0 );
// if ( static_cast<Attribute*>( args[0].addr )->IsDefined() &&
// static_cast<Attribute*>( args[1].addr )->IsDefined() )
// {
try
{
R res = O()(on_request_arg(args[0].addr, (A1*)0) ,
on_request_arg(args[1].addr, (A2*)0));
setResultValue(result.addr, res);
delPointer(res);
// result.addr = result_value( O()
// ( on_request_arg( args[0].addr, (A1*)0 ),
// on_request_arg( args[1].addr, (A2*)0 ) ) );
return 0;
}
catch( const std::exception& e ) {
std::cerr << e.what() << endl;
}
// }
on_close_arg( args[0].addr, (A1*)0 );
on_close_arg( args[1].addr, (A2*)0 );
// static_cast<Attribute*>(result.addr)->SetDefined( false );
return 0;
}
template< typename O >
int ternary_value_map( Word* args, Word& result, int, Word&, Supplier s )
{
typedef typename O::first_argument_type A1;
typedef typename O::second_argument_type A2;
typedef typename O::third_argument_type A3;
typedef typename O::result_type R;
result = qp->ResultStorage( s );
on_open_arg( args[0].addr, (A1*)0 );
on_open_arg( args[1].addr, (A2*)0 );
on_open_arg( args[2].addr, (A3*)0 );
// if ( static_cast<Attribute*>( args[0].addr )->IsDefined() &&
// static_cast<Attribute*>( args[1].addr )->IsDefined() &&
// static_cast<Attribute*>( args[2].addr )->IsDefined() )
// {
try
{
R res = O()
( on_request_arg( args[0].addr, (A1*)0 ),
on_request_arg( args[1].addr, (A2*)0 ),
on_request_arg( args[2].addr, (A3*)0 ) );
setResultValue(result.addr, res);
delPointer(res);
return 0;
}
catch( const std::exception& e ) {
std::cerr << e.what() << endl;
}
// }
on_close_arg( args[0].addr, (A1*)0 );
on_close_arg( args[1].addr, (A2*)0 );
on_close_arg( args[2].addr, (A3*)0 );
// static_cast<Attribute*>(result.addr)->SetDefined( false );
return 0;
}
//-----------------------------------------------------------------------------
// Stream producing value mapping functions
template< typename O >
int unary_stream_value_map( Word* args, Word& result,
int message, Word& local, Supplier s )
{
typedef typename O::argument_type A;
typedef typename O::result_type R;
if ( OPEN == message )
{
try {
local.addr = new O( on_open_arg( args[0].addr, (A*)0 ),
nl->Second( GetTupleResultType(s) ) );
}
catch( std::exception const& e ) {
std::cerr << e.what() << endl;
local.addr = 0;
}
}
else if ( CLOSE == message )
{
on_close_arg( args[0].addr, (A*)0 );
if ( local.addr )
{
delete static_cast< O* >( local.addr );
local.addr = 0;
}
}
else if ( REQUEST == message )
{
if ( local.addr )
{
try
{
O* op = static_cast< O* >( local.addr );
R r = (*op)( on_request_arg( args[0].addr, (A*)0 ) );
if ( r.first )
{
result = qp->ResultStorage( s );
result.addr = result_value( r.second );
return YIELD;
} else {
delPointer(r.second);
}
}
catch( const std::exception& e ){
std::cerr << e.what() << endl;
}
}
return CANCEL;
}
return 0;
}
template< typename O >
int binary_stream_value_map( Word* args, Word& result,
int message, Word& local, Supplier s )
{
typedef typename O::first_argument_type A1;
typedef typename O::second_argument_type A2;
typedef typename O::result_type R;
if ( OPEN == message )
{
try
{
local.addr = new O( on_open_arg( args[0].addr, (A1*)0 ),
on_open_arg( args[1].addr, (A2*)0 ),
nl->Second( GetTupleResultType(s) ) );
}
catch( std::exception const& e ) {
std::cerr << e.what() << endl;
local.addr = 0;
}
}
else if ( CLOSE == message )
{
on_close_arg( args[0].addr, (A1*)0 );
on_close_arg( args[1].addr, (A2*)0 );
if ( local.addr )
{
delete static_cast< O* >( local.addr );
local.addr = 0;
}
}
else if ( REQUEST == message )
{
if ( local.addr )
{
try
{
O* op = static_cast< O* >( local.addr );
R r = (*op)( on_request_arg( args[0].addr, (A1*)0 ),
on_request_arg( args[1].addr, (A2*)0 ) );
if ( r.first )
{
result = qp->ResultStorage( s );
result.addr = result_value( r.second );
return YIELD;
}
}
catch( const std::exception& e ){
std::cerr << e.what() << endl;
}
}
return CANCEL;
}
return 0;
}
//-----------------------------------------------------------------------------
// Stream consuming aggregate value mapping functions
template< typename A, typename OP >
struct unary_aggregate
: std::unary_function< StreamIterator< A >, typename OP::result_type >
{
typedef typename OP::result_type R;
R operator()( const StreamIterator< A >& stream )
{
OP op;
for( StreamIterator< A > s(stream); s.valid(); ++s )
op( on_request_arg( *s, (typename OP::argument_type*)0 ) );
return op.result();
}
};
template< typename A, typename OP >
struct binary_aggregate : std::binary_function< StreamIterator< A >,
Function< A*, typename OP::result_type >,
typename OP::result_type >
{
typedef typename OP::result_type R;
R operator()( const StreamIterator< A >& stream,
const Function< A*, R >& fun )
{
OP op;
for( StreamIterator<A> s(stream); s.valid(); ++s )
op( fun(*s) );
return op.result();
}
};
#endif // SECONDO_VALUE_MAPPING_HPP