template <typename T>
TupleList<T>::TupleList()
{
    listLength = 0;
}

template <typename T>
void TupleList<T>::Reset()
{
    std::vector<T>().swap(tupleList);
}

template <typename T>
T &TupleList<T>::operator[](int index)
{
    return tupleList[index];
}

template <typename T>
void TupleList<T>::GetTupleMetrics(TupleMetrics &ptm)
{
    ptm = tm;
}

template <typename T>
void TupleList<T>::SetTupleMetrics(TupleMetrics &ptm)
{
    tm = ptm;
}

template <typename T>
int TupleList<T>::size()
{
    return tupleList.size();
}

template <typename T>
int TupleList<T>::GetLength()
{
    return tupleList.size();
}

template <typename T>
int TupleList<T>::InitFromFile(std::string &fileName)
{
    std::ifstream listIn;
    listIn.open(fileName.c_str(), std::ios_base::binary);
    if (!listIn) return 0;
    listIn.read((char *)&listLength, sizeof(int));
    listIn.read((char *)&tm.tupleSize, sizeof(int));
    tm.InitializeMask();
    tupleList.resize(listLength);
    listIn.read((char *)&tupleList[0], sizeof(T) * listLength);
    return 1;
}

template <typename T>
void TupleList<T>::clear()
{
    tupleList.clear();
    listLength = 0;
}

template <typename T>
int TupleList<T>::WriteToFile(std::string &fileName)
{
    std::ofstream listOut;
    listOut.open(fileName.c_str(), std::ios_base::binary);
    if (!listOut) return 0;
    listLength = tupleList.size();
    std::cout << "writing tuple lis of length " << listLength << std::endl;
    listOut.write((char *)&listLength, sizeof(int));
    listOut.write((char *)&tm.tupleSize, sizeof(int));
    listOut.write((char *)&tupleList[0], sizeof(T) * listLength);
    return 1;
}

//
// Find one instance of a match.
//
template <typename T>
int TupleList<T>::Find(T &tuple)
{
    typename std::vector<T>::const_iterator begin, end, matchIt;
    begin = tupleList.begin();
    end = tupleList.end();
    matchIt = lower_bound(begin, end, tuple);
    if (*matchIt != tuple) {
        return -1;
    } else {
        return matchIt - tupleList.begin();
    }
}

//
// Find the boundaries of all instances of a match.
//
template <typename T>
void TupleList<T>::FindAll(T &tuple, typename std::vector<T>::const_iterator &firstPos,
                           typename std::vector<T>::const_iterator &endPos)
{
    firstPos = lower_bound(tupleList.begin(), tupleList.end(), tuple);
    typename std::vector<T>::const_iterator firstPos2;
    endPos = tupleList.end();
    endPos = upper_bound(firstPos, endPos, tuple);
    while (endPos != tupleList.end()) {
        if (*endPos != tuple) {
            return;
        } else {
            endPos++;
        }
    }
}

template <typename T>
void TupleList<T>::Append(T &tuple)
{
    tupleList.push_back(tuple);
}

template <typename T>
void TupleList<T>::Insert(T &tuple)
{
    // insert and maintain order.
    typename std::vector<T>::iterator pos;
    pos = std::lower_bound(tupleList.begin(), tupleList.end(), tuple);
    tupleList.insert(pos, tuple);
}

template <typename T>
void TupleList<T>::Sort()
{
    sort(tupleList.begin(), tupleList.end());
}

template <typename T>
void TupleList<T>::Print()
{
    int i;
    for (i = 0; i < tupleList.size(); i++) {
        std::cout << tupleList[i].tuple << std::endl;
    }
}
