/usr/include/boost/phoenix/function
Edit: /usr/include/boost/phoenix/function/lazy_list.hpp (49435B)
////////////////////////////////////////////////////////////////////////////
// lazy_list.hpp
//
// Build lazy operations for Phoenix equivalents for FC++
//
// These are equivalents of the Boost FC++ functoids in list.hpp
//
// Implemented so far:
//
// head tail null
//
// strict_list
and associated iterator.
//
// list and odd_list
//
// cons cat
//
// Comparisons between list and odd_list types and separately for strict_list.
//
// NOTES: There is a fix at the moment as I have not yet sorted out
// how to get back the return type of a functor returning a list type.
// For the moment I have fixed this as odd_list at two locations,
// one in list and one in Cons. I am going to leave it like this
// for now as reading the code, odd_list seems to be correct.
//
// I am also not happy at the details needed to detect types in Cons.
//
// I think the structure of this file is now complete.
// John Fletcher February 2015.
//
////////////////////////////////////////////////////////////////////////////
/*=============================================================================
Copyright (c) 2000-2003 Brian McNamara and Yannis Smaragdakis
Copyright (c) 2001-2007 Joel de Guzman
Copyright (c) 2015 John Fletcher
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
///////////////////////////////////////////////////////////////////////
// This is from Boost FC++ list.hpp reimplemented without Fun0 or Full0
///////////////////////////////////////////////////////////////////////
/*
concept ListLike: Given a list representation type L
L inherits ListLike and has
// typedefs just show typical values
typedef T value_type
typedef L force_result_type
typedef L delay_result_type
typedef L tail_result_type
template struct cons_rebind {
typedef L type; // force type
typedef L delay_type; // delay type
};
L()
L( a_unique_type_for_nil )
template L(F) // F :: ()->L
constructor: force_result_type( T, L )
template
constructor: force_result_type( T, F ) // F :: ()->L
template
L( It, It )
// FIX THIS instead of operator bool(), does Boost have something better?
operator bool() const
force_result_type force() const
delay_result_type delay() const
T head() const
tail_result_type tail() const
static const bool is_lazy; // true if can represent infinite lists
typedef const_iterator;
typedef const_iterator iterator; // ListLikes are immutable
iterator begin() const
iterator end() const
*/
//////////////////////////////////////////////////////////////////////
// End of section from Boost FC++ list.hpp
//////////////////////////////////////////////////////////////////////
#ifndef BOOST_PHOENIX_FUNCTION_LAZY_LIST
#define BOOST_PHOENIX_FUNCTION_LAZY_LIST
#include
#include
#include
#include
#include
//#include "lazy_reuse.hpp"
namespace boost {
namespace phoenix {
//////////////////////////////////////////////////////////////////////
// These are the list types being declared.
//////////////////////////////////////////////////////////////////////
template class strict_list;
namespace impl {
template class list;
template class odd_list;
}
// in ref_count.hpp in BoostFC++ now in lazy_operator.hpp
//typedef unsigned int RefCountType;
//////////////////////////////////////////////////////////////////////
// a_unique_type_for_nil moved to lazy_operator.hpp.
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
// Distinguish lazy lists (list and odd_list) from strict_list.
//////////////////////////////////////////////////////////////////////
namespace lazy {
// Copied from Boost FC++ list.hpp
template struct ensure_lazy_helper {};
template struct ensure_lazy_helper {
static void requires_lazy_list_to_prevent_infinite_recursion() {}
};
template
void ensure_lazy() {
ensure_lazy_helper::
requires_lazy_list_to_prevent_infinite_recursion();
}
}
//////////////////////////////////////////////////////////////////////
// Provide remove reference for types defined for list types.
//////////////////////////////////////////////////////////////////////
namespace result_of {
template < typename L >
class ListType
{
public:
typedef typename boost::remove_reference::type LType;
typedef typename LType::value_type value_type;
typedef typename LType::tail_result_type tail_result_type;
typedef typename LType::force_result_type force_result_type;
typedef typename LType::delay_result_type delay_result_type;
};
template <>
class ListType
{
public:
typedef a_unique_type_for_nil LType;
//typedef a_unique_type_for_nil value_type;
};
template
struct ResultType {
typedef typename impl::odd_list type;
};
}
//////////////////////////////////////////////////////////////////////
// ListLike is a property inherited by any list type to enable it to
// work with the functions being implemented in this file.
// It provides the check for the structure described above.
//////////////////////////////////////////////////////////////////////
namespace listlike {
struct ListLike {}; // This lets us use is_base_and_derived() to see
// (at compile-time) what classes are user-defined lists.
template struct ensure_lazy_helper {};
template struct ensure_lazy_helper {
static void requires_lazy_list_to_prevent_infinite_recursion() {}
};
template
void ensure_lazy() {
ensure_lazy_helper::
requires_lazy_list_to_prevent_infinite_recursion();
}
template
struct EnsureListLikeHelp {
static void trying_to_call_a_list_function_on_a_non_list() {}
};
template struct EnsureListLikeHelp { };
template
void EnsureListLike() {
typedef typename result_of::ListType::LType LType;
EnsureListLikeHelp::value>::
trying_to_call_a_list_function_on_a_non_list();
}
template
bool is_a_unique_type_for_nil(const L& /*l*/) {
return false;
}
template <>
bool is_a_unique_type_for_nil
(const a_unique_type_for_nil& /* n */) {
return true;
}
template
struct detect_nil {
static const bool is_nil = false;
};
template <>
struct detect_nil {
static const bool is_nil = true;
};
template <>
struct detect_nil {
static const bool is_nil = true;
};
template <>
struct detect_nil {
static const bool is_nil = true;
};
}
//////////////////////////////////////////////////////////////////////
// Implement lazy functions for list types. cat and cons come later.
//////////////////////////////////////////////////////////////////////
#ifndef BOOST_PHOENIX_FUNCTION_MAX_LAZY_LIST_LENGTH
#define BOOST_PHOENIX_FUNCTION_MAX_LAZY_LIST_LENGTH 1000
#endif
namespace impl {
struct Head
{
template
struct result;
template
struct result
{
typedef typename result_of::ListType::value_type type;
};
template
typename result::type
operator()(const L & l) const
{
listlike::EnsureListLike();
return l.head();
}
};
struct Tail
{
template
struct result;
template
struct result
{
typedef typename result_of::ListType::tail_result_type type;
};
template
typename result::type
operator()(const L & l) const
{
listlike::EnsureListLike();
return l.tail();
}
};
struct Null
{
template
struct result;
template
struct result
{
typedef bool type;
};
template
typename result::type
//bool
operator()(const L& l) const
{
listlike::EnsureListLike();
return !l;
}
};
struct Delay {
template
struct result;
template
struct result
{
typedef typename result_of::ListType::delay_result_type type;
};
template
typename result::type
operator()(const L & l) const
{
listlike::EnsureListLike();
return l.delay();
}
};
struct Force {
template
struct result;
template
struct result
{
typedef typename result_of::ListType::force_result_type type;
};
template
typename result::type
operator()(const L & l) const
{
listlike::EnsureListLike();
return l.force();
}
};
}
//BOOST_PHOENIX_ADAPT_CALLABLE(head, impl::head, 1)
//BOOST_PHOENIX_ADAPT_CALLABLE(tail, impl::tail, 1)
//BOOST_PHOENIX_ADAPT_CALLABLE(null, impl::null, 1)
typedef boost::phoenix::function Head;
typedef boost::phoenix::function Tail;
typedef boost::phoenix::function Null;
typedef boost::phoenix::function Delay;
typedef boost::phoenix::function Force;
Head head;
Tail tail;
Null null;
Delay delay;
Force force;
//////////////////////////////////////////////////////////////////////
// These definitions used for strict_list are imported from BoostFC++
// unchanged.
//////////////////////////////////////////////////////////////////////
namespace impl {
template
struct strict_cons : public boost::noncopyable {
mutable RefCountType refC;
T head;
typedef boost::intrusive_ptr tail_type;
tail_type tail;
strict_cons( const T& h, const tail_type& t ) : refC(0), head(h), tail(t) {}
};
template
void intrusive_ptr_add_ref( const strict_cons* p ) {
++ (p->refC);
}
template
void intrusive_ptr_release( const strict_cons* p ) {
if( !--(p->refC) ) delete p;
}
template
class strict_list_iterator {
typedef boost::intrusive_ptr > rep_type;
rep_type l;
bool is_nil;
void advance() {
l = l->tail;
if( !l )
is_nil = true;
}
class Proxy { // needed for operator->
const T x;
friend class strict_list_iterator;
Proxy( const T& xx ) : x(xx) {}
public:
const T* operator->() const { return &x; }
};
public:
typedef std::input_iterator_tag iterator_category;
typedef T value_type;
typedef ptrdiff_t difference_type;
typedef T* pointer;
typedef T& reference;
strict_list_iterator() : l(), is_nil(true) {}
explicit strict_list_iterator( const rep_type& ll ) : l(ll), is_nil(!ll) {}
const T operator*() const { return l->head; }
const Proxy operator->() const { return Proxy(l->head); }
strict_list_iterator& operator++() {
advance();
return *this;
}
const strict_list_iterator operator++(int) {
strict_list_iterator i( *this );
advance();
return i;
}
bool operator==( const strict_list_iterator& i ) const {
return is_nil && i.is_nil;
}
bool operator!=( const strict_list_iterator& i ) const {
return ! this->operator==(i);
}
};
}
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
template
class strict_list : public listlike::ListLike
{
typedef boost::intrusive_ptr > rep_type;
rep_type rep;
struct Make {};
template
static rep_type help( Iter a, const Iter& b ) {
rep_type r;
while( a != b ) {
T x( *a );
r = rep_type( new impl::strict_cons( x, r ) );
++a;
}
return r;
}
public:
static const bool is_lazy = false;
typedef T value_type;
typedef strict_list force_result_type;
typedef strict_list delay_result_type;
typedef strict_list tail_result_type;
template struct cons_rebind {
typedef strict_list type;
typedef strict_list delay_type;
};
strict_list( Make, const rep_type& r ) : rep(r) {}
strict_list() : rep() {}
strict_list( a_unique_type_for_nil ) : rep() {}
template
strict_list( const F& f ) : rep( f().rep ) {
// I cannot do this yet.
//functoid_traits::template ensure_accepts<0>::args();
}
strict_list( const T& x, const strict_list& y )
: rep( new impl::strict_cons(x,y.rep) ) {}
template
strict_list( const T& x, const F& f )
: rep( new impl::strict_cons(x,f().rep) ) {}
operator bool() const { return (bool)rep; }
force_result_type force() const { return *this; }
delay_result_type delay() const { return *this; }
T head() const {
#ifndef BOOST_PHOENIX_NO_LAZY_EXCEPTIONS
if( !*this )
throw lazy_exception("Tried to take head() of empty strict_list");
#endif
return rep->head;
}
tail_result_type tail() const {
#ifndef BOOST_PHOENIX_NO_LAZY_EXCEPTIONS
if( !*this )
throw lazy_exception("Tried to take tail() of empty strict_list");
#endif
return strict_list(Make(),rep->tail);
}
template
strict_list( const Iter& a, const Iter& b ) : rep( rep_type() ) {
// How ironic. We need to reverse the iterator range in order to
// non-recursively build this!
std::vector tmp(a,b);
rep = help( tmp.rbegin(), tmp.rend() );
}
// Since the strict_cons destructor can't call the strict_list
// destructor, the "simple" iterative destructor is correct and
// efficient. Hurray.
~strict_list() { while(rep && (rep->refC == 1)) rep = rep->tail; }
// The following helps makes strict_list almost an STL "container"
typedef impl::strict_list_iterator const_iterator;
typedef const_iterator iterator; // strict_list is immutable
iterator begin() const { return impl::strict_list_iterator( rep ); }
iterator end() const { return impl::strict_list_iterator(); }
};
// All of these null head and tail are now non lazy using e.g. null(a)().
// They need an extra () e.g. null(a)().
template
bool operator==( const strict_list& a, a_unique_type_for_nil ) {
return null(a)();
}
template
bool operator==( a_unique_type_for_nil, const strict_list& a ) {
return null(a)();
}
template
bool operator==( const strict_list& a, const strict_list& b ) {
if( null(a)() && null(b)() )
return true;
if( null(a)() || null(b)() )
return false;
return (head(a)()==head(b)()) &&
(tail(a)()==tail(b)());
}
template
bool operator<( const strict_list& a, const strict_list& b ) {
if( null(a)() && !null(b)() ) return true;
if( null(b)() ) return false;
if( head(b)() < head(a)() ) return false;
if( head(a)() < head(b)() ) return true;
return (tail(a)() < tail(b)());
}
template
bool operator<( const strict_list&, a_unique_type_for_nil ) {
return false;
}
template
bool operator<( a_unique_type_for_nil, const strict_list& b ) {
return !(null(b)());
}
//////////////////////////////////////////////////////////////////////
// Class list is the primary interface to the user for lazy lists.
//////////////////////////////////////////////////////////////////////{
namespace impl {
using fcpp::INV;
using fcpp::VAR;
using fcpp::reuser2;
struct CacheEmpty {};
template class Cache;
template class odd_list;
template class list_iterator;
template
struct ListItHelp2 /*: public c_fun_type >*/ {
// This will need a return type.
typedef odd_list return_type;
odd_list operator()( It begin, const It& end,
reuser2,It,It> r = NIL ) const;
};
template struct cvt;
template struct ListHelp;
template Cache* xempty_helper();
template struct ConsHelp2;
struct ListRaw {};
template
class list : public listlike::ListLike
{
// never NIL, unless an empty odd_list
boost::intrusive_ptr > rep;
template friend class Cache;
template friend class odd_list;
template friend struct ConsHelp2;
template friend struct cvt;
list( const boost::intrusive_ptr >& p ) : rep(p) { }
list( ListRaw, Cache* p ) : rep(p) { }
bool priv_isEmpty() const {
return rep->cache().second.rep == Cache::XNIL();
}
T priv_head() const {
#ifndef BOOST_PHOENIX_NO_LAZY_EXCEPTIONS
if( priv_isEmpty() )
throw lazy_exception("Tried to take head() of empty list");
#endif
return rep->cache().first();
}
list priv_tail() const {
#ifndef BOOST_PHOENIX_NO_LAZY_EXCEPTIONS
if( priv_isEmpty() )
throw lazy_exception("Tried to take tail() of empty list");
#endif
return rep->cache().second;
}
public:
static const bool is_lazy = true;
typedef T value_type;
typedef list tail_result_type;
typedef odd_list force_result_type;
typedef list delay_result_type;
template struct cons_rebind {
typedef odd_list type;
typedef list delay_type;
};
list( a_unique_type_for_nil ) : rep( Cache::XEMPTY() ) { }
list() : rep( Cache::XEMPTY() ) { }
template // works on both ()->odd_list and ()->list
// At the moment this is fixed for odd_list.
// I need to do more work to get the general result.
list( const F& f )
: rep( ListHelp >()(f) ) { }
//: rep( ListHelp()(f) ) { }
operator bool() const { return !priv_isEmpty(); }
const force_result_type& force() const { return rep->cache(); }
const delay_result_type& delay() const { return *this; }
// Note: force returns a reference;
// implicit conversion now returns a copy.
operator odd_list() const { return force(); }
T head() const { return priv_head(); }
tail_result_type tail() const { return priv_tail(); }
// The following helps makes list almost an STL "container"
typedef list_iterator const_iterator;
typedef const_iterator iterator; // list is immutable
iterator begin() const { return list_iterator( *this ); }
iterator end() const { return list_iterator(); }
// end of list
};
//////////////////////////////////////////////////////////////////////
// Class odd_list is not normally accessed by the user.
//////////////////////////////////////////////////////////////////////
struct OddListDummyY {};
template
class odd_list : public listlike::ListLike
{
public:
typedef
typename boost::type_with_alignment::value>::type
xfst_type;
private:
union { xfst_type fst; unsigned char dummy[sizeof(T)]; };
const T& first() const {
return *static_cast(static_cast(&fst));
}
T& first() {
return *static_cast(static_cast(&fst));
}
list second; // If XNIL, then this odd_list is NIL
template friend class list;
template friend class Cache;
odd_list( OddListDummyY )
: second( Cache::XBAD() ) { }
void init( const T& x ) {
new (static_cast(&fst)) T(x);
}
bool fst_is_valid() const {
if( second.rep != Cache::XNIL() )
if( second.rep != Cache::XBAD() )
return true;
return false;
}
bool priv_isEmpty() const { return second.rep == Cache::XNIL(); }
T priv_head() const {
#ifndef BOOST_PHOENIX_NO_LAZY_EXCEPTIONS
if( priv_isEmpty() )
throw lazy_exception("Tried to take head() of empty odd_list");
#endif
return first();
}
list priv_tail() const {
#ifndef BOOST_PHOENIX_NO_LAZY_EXCEPTIONS
if( priv_isEmpty() )
throw lazy_exception("Tried to take tail() of empty odd_list");
#endif
return second;
}
public:
static const bool is_lazy = true;
typedef T value_type;
typedef list tail_result_type;
typedef odd_list force_result_type;
typedef list delay_result_type;
template struct cons_rebind {
typedef odd_list type;
typedef list delay_type;
};
odd_list() : second( Cache::XNIL() ) { }
odd_list( a_unique_type_for_nil ) : second( Cache::XNIL() ) { }
odd_list( const T& x, const list& y ) : second(y) { init(x); }
odd_list( const T& x, a_unique_type_for_nil ) : second(NIL) { init(x); }
odd_list( const odd_list& x ) : second(x.second) {
if( fst_is_valid() ) {
init( x.first() );
}
}
template
odd_list( It begin, const It& end )
: second( begin==end ? Cache::XNIL() :
( init(*begin++), list( begin, end ) ) ) {}
odd_list& operator=( const odd_list& x ) {
if( this == &x ) return *this;
if( fst_is_valid() ) {
if( x.fst_is_valid() )
first() = x.first();
else
first().~T();
}
else {
if( x.fst_is_valid() )
init( x.first() );
}
second = x.second;
return *this;
}
~odd_list() {
if( fst_is_valid() ) {
first().~T();
}
}
operator bool() const { return !priv_isEmpty(); }
const force_result_type& force() const { return *this; }
delay_result_type delay() const { return list(*this); }
T head() const { return priv_head(); }
tail_result_type tail() const { return priv_tail(); }
// The following helps makes odd_list almost an STL "container"
typedef list_iterator const_iterator;
typedef const_iterator iterator; // odd_list is immutable
iterator begin() const { return list_iterator( this->delay() ); }
iterator end() const { return list_iterator(); }
// end of odd_list
};
//////////////////////////////////////////////////////////////////////
// struct cvt
//////////////////////////////////////////////////////////////////////
// This converts ()->list to ()->odd_list.
// In other words, here is the 'extra work' done when using the
// unoptimized interface.
template
struct cvt /*: public c_fun_type >*/ {
typedef odd_list return_type;
F f;
cvt( const F& ff ) : f(ff) {}
odd_list operator()() const {
list l = f();
return l.force();
}
};
//////////////////////////////////////////////////////////////////////
// Cache and associated functions.
//////////////////////////////////////////////////////////////////////
// I malloc a RefCountType to hold the refCount and init it to 1 to ensure the
// refCount will never get to 0, so the destructor-of-global-object
// order at the end of the program is a non-issue. In other words, the
// memory allocated here is only reclaimed by the operating system.
template
Cache* xnil_helper() {
void *p = std::malloc( sizeof(RefCountType) );
*((RefCountType*)p) = 1;
return static_cast*>( p );
}
template
Cache* xnil_helper_nil() {
Cache* p = xnil_helper();
return p;
}
template
Cache* xnil_helper_bad() {
Cache* p = xnil_helper();
return p;
}
template
Cache* xempty_helper() {
Cache* p = new Cache( CacheEmpty() );
return p;
}
// This makes a boost phoenix function type with return type
// odd_list
template
struct fun0_type_helper{
typedef boost::function0 > fun_type;
typedef boost::phoenix::function phx_type;
};
template
struct make_fun0_odd_list {
typedef typename fun0_type_helper::fun_type fun_type;
typedef typename fun0_type_helper::phx_type phx_type;
typedef phx_type result_type;
template
result_type operator()(const F& f) const
{
fun_type ff(f);
phx_type g(ff);
return g;
}
// Overload for the case where it is a boost phoenix function already.
template
typename boost::phoenix::function operator()
(const boost::phoenix::function& f) const
{
return f;
}
};
template
class Cache : boost::noncopyable {
mutable RefCountType refC;
// This is the boost::function type
typedef typename fun0_type_helper::fun_type fun_odd_list_T;
// This is the boost::phoenix::function type;
typedef typename fun0_type_helper::phx_type fun0_odd_list_T;
mutable fun0_odd_list_T fxn;
mutable odd_list val;
// val.second.rep can be XBAD, XNIL, or a valid ptr
// - XBAD: val is invalid (fxn is valid)
// - XNIL: this is the empty list
// - anything else: val.first() is head, val.second is tail()
// This functoid should never be called; it represents a
// self-referent Cache, which should be impossible under the current
// implementation. Nonetheless, we need a 'dummy' function object to
// represent invalid 'fxn's (val.second.rep!=XBAD), and this
// implementation seems to be among the most reasonable.
struct blackhole_helper /*: c_fun_type< odd_list >*/ {
typedef odd_list return_type;
odd_list operator()() const {
#ifndef BOOST_PHOENIX_NO_LAZY_EXCEPTIONS
throw lazy_exception("You have entered a black hole.");
#else
return odd_list();
#endif
}
};
// Don't get rid of these XFOO() functions; they impose no overhead,
// and provide a useful place to add debugging code for tracking down
// before-main()-order-of-initialization problems.
static const boost::intrusive_ptr >& XEMPTY() {
static boost::intrusive_ptr > xempty( xempty_helper() );
return xempty;
}
static const boost::intrusive_ptr