// ---------------------------------------------------------------------------
// - Ati.hpp                                                                 -
// - afnix:mth module - abstract trace interface definitions                 -
// ---------------------------------------------------------------------------
// - This program is free software;  you can redistribute it  and/or  modify -
// - it provided that this copyright notice is kept intact.                  -
// -                                                                         -
// - This program  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.  In no event shall -
// - the copyright holder be liable for any  direct, indirect, incidental or -
// - special damages arising in any way out of the use of this software.     -
// ---------------------------------------------------------------------------
// - copyright (c) 1999-2023 amaury darsch                                   -
// ---------------------------------------------------------------------------

#ifndef  AFNIX_ATI_HPP
#define  AFNIX_ATI_HPP

#ifndef  AFNIX_SERIAL_HPP
#include "Serial.hpp"
#endif

namespace afnix {

  /// This Ati class is an abstract class that models the behavior of a
  /// typed matrix trace. The class defines the trace size.
  /// @author amaury darsch

  class Ati : public virtual Serial {
  protected:
    /// the trace size
    t_long d_size;

  public:
    /// create a null trace
    Ati (void);

    /// create a trace by size
    /// @param size the trace size
    Ati (const t_long size);

    /// copy construct this trace
    /// @param that the trace to copy
    Ati (const Ati& that);

    /// copy move this trace
    /// @param that the trace to move
    Ati (Ati&& that) noexcept;

    /// assign a trace into this one
    /// @param that the trace to assign
    Ati& operator = (const Ati& that);

    /// move a trace into this one
    /// @param that the trace to move
    Ati& operator = (Ati&& that) noexcept;

    /// @return the trace size
    virtual t_long getsize (void) const;

    /// reset this trace
    virtual void reset (void) =0;

    /// clear this trace
    virtual void clear (void) =0;

    /// preset this trace
    virtual void preset (void) =0;

    /// resize this trace
    /// @param size the new trace size
    virtual void resize (const t_long size) =0;

    /// @return true if the trace is nil
    virtual bool isnil (void) const =0;

    /// @return a vector of literals
    virtual Vector tovector (void) const =0;

    /// @return the trace format
    virtual String tofrmt (void) const;
    
  public:
    /// @return true if the given quark is defined
    bool isquark (const long quark, const bool hflg) const override;

    /// apply this object with a set of arguments and a quark
    /// @param zobj  the current evaluable
    /// @param nset  the current nameset    
    /// @param quark the quark to apply these arguments
    /// @param argv  the arguments to apply
    Object* apply (Evaluable* zobj, Nameset* nset, const long quark,
                   Vector* argv) override;
  };
}

#endif
