/* ----------------------------------------------------------------------------
 * This file was automatically generated by SWIG (http://www.swig.org).
 * Version 2.0.8
 *
 * Do not make changes to this file unless you know what you are doing--modify
 * the SWIG interface file instead.
 * ----------------------------------------------------------------------------- */

package com.savoirfairelinux.sflphone.service;

public class IntVect {
  private long swigCPtr;
  protected boolean swigCMemOwn;

  protected IntVect(long cPtr, boolean cMemoryOwn) {
    swigCMemOwn = cMemoryOwn;
    swigCPtr = cPtr;
  }

  protected static long getCPtr(IntVect obj) {
    return (obj == null) ? 0 : obj.swigCPtr;
  }

  protected void finalize() {
    delete();
  }

  public synchronized void delete() {
    if (swigCPtr != 0) {
      if (swigCMemOwn) {
        swigCMemOwn = false;
        SFLPhoneserviceJNI.delete_IntVect(swigCPtr);
      }
      swigCPtr = 0;
    }
  }

  public IntVect() {
    this(SFLPhoneserviceJNI.new_IntVect__SWIG_0(), true);
  }

  public IntVect(long n) {
    this(SFLPhoneserviceJNI.new_IntVect__SWIG_1(n), true);
  }

  public long size() {
    return SFLPhoneserviceJNI.IntVect_size(swigCPtr, this);
  }

  public long capacity() {
    return SFLPhoneserviceJNI.IntVect_capacity(swigCPtr, this);
  }

  public void reserve(long n) {
    SFLPhoneserviceJNI.IntVect_reserve(swigCPtr, this, n);
  }

  public boolean isEmpty() {
    return SFLPhoneserviceJNI.IntVect_isEmpty(swigCPtr, this);
  }

  public void clear() {
    SFLPhoneserviceJNI.IntVect_clear(swigCPtr, this);
  }

  public void add(int x) {
    SFLPhoneserviceJNI.IntVect_add(swigCPtr, this, x);
  }

  public int get(int i) {
    return SFLPhoneserviceJNI.IntVect_get(swigCPtr, this, i);
  }

  public void set(int i, int val) {
    SFLPhoneserviceJNI.IntVect_set(swigCPtr, this, i, val);
  }

}
