/*
 * ASTL - the Automaton Standard Template Library.
 * C++ generic components for Finite State Machine handling.
 * Copyright (C) 2000 Vincent Le Maout (vlemaout@lexiquest.fr).
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * 
 * This library 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
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 */


#ifndef ASTL_CLASS_FILTER_CURSORS
#define ASTL_CLASS_FILTER_CURSORS

// Defines:
// 1. template filter_in_cursor  (forward cursor adapter)
// 2. template filter_out_cursor (forward cursor adapter)

// A filter cursor is a forward cursor adapter which maps
// alphabet before calling any methods involving letters of transitions
// A filter_in_cursor maps the alphabet before calling forward(a) and find(a) 
// A filter_out_cursor maps the alphabet after calling letter()

// filter_in_cursor
//
// Instanciation parameters:
// 1. ForwardCursor:  the type of the cursor to be adapted
// 2. ObjectFunction: a unary function from unsigned int to unsigned int (filter in)
//
// Requirements:
// None
//

template <class ForwardCursor, class ObjectFunction>
class filter_in_cursor : public ForwardCursor
{
protected:
  ObjectFunction f;

public:
  typedef filter_in_cursor self;
  typedef ForwardCursor super;
  typedef typename super::State State;
  typedef typename ObjectFunction::argument_type Alphabet;

  filter_in_cursor(const super &x = super(), const ObjectFunction &of = ObjectFunction())
    : super(x), f(of)
  { }

  bool forward(const Alphabet &a) {
    return super::forward(f(a));
  }

  bool find(const Alphabet &a) {
    return super::find(f(a));
  }

  self& operator= (const State &x) {
    super::operator=(x);
    return *this;
  }
};


// filter_out_cursor
//
// Instanciation parameters:
// 1. ForwardCursor:  the type of the cursor to be adapted
// 2. ObjectFunction: a unary function from unsigned int to unsigned int (filter out)
//
// Requirements
// None

template <class ForwardCursor, class ObjectFunction>
class filter_out_cursor : public ForwardCursor
{
protected:
  ObjectFunction f;

public:
  typedef filter_out_cursor self;
  typedef ForwardCursor     super;
  typedef typename ObjectFunction::result_type Alphabet;

  filter_out_cursor(const super &x, const ObjectFunction &of = ObjectFunction())
    : super(x), f(of)
  { }

  Alphabet letter() const {
    return f(super::letter());
  }
};

// Helper functions:
template <class ForwardCursor, class ObjectFunction>
filter_out_cursor<ForwardCursor, ObjectFunction>
filter_outc(const ForwardCursor &x, const ObjectFunction &f) {
  return filter_out_cursor<ForwardCursor, ObjectFunction>(x, f);
}

template <class ForwardCursor, class ObjectFunction>
filter_in_cursor<ForwardCursor, ObjectFunction>
filter_inc(const ForwardCursor &x, const ObjectFunction &f) {
  return filter_in_cursor<ForwardCursor, ObjectFunction>(x, f);
}


#endif // ASTL_CLASS_FILTER_CURSORS




