// $Id: branchtag.h,v 1.5 2018/01/03 21:33:03 mkkuhner Exp $

/*
Copyright 2002-2005 Mary K. Kuhner, Peter Beerli, and Joseph Felsenstein

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

*/

/* Authors: Peter Beerli, Mary Kuhner, Jon Yamato and Joseph Felsenstein */


/*******************************************************************
 Class BranchTag tracks and manages the semi-unique ID number of each
 "branch".  Semi-unique, in that if two (or more) branches represent the
 same "branch", then they will share the same ID number.

 Implementationwise, BranchTags are a shared pointer that on construction
 pulls a new unique ID number and initializes a counter.  Copying one
 increments the counter.  Destroying one decrements the counter.  On
 decrement if the counter reaches "zero", then the ID is freed for reuse.

 This class makes heavy use of static members--the member BeginBranchIDs,
 with an argument equal to the number of needed ids, must be called before
 any branch ids are handed out.  The call will look something like this:
     long max_number_of_concurrent_branches = 1000000;
     BranchTag::BeginBranchIDs(max_number_of_concurrent_branches);

 Written by Jon Yamato
********************************************************************/

#ifndef BRANCHTAG_H
#define BRANCHTAG_H

#include <deque>

#include "vectorx.h"

class BranchTag
{
  private:
    LongVec1d::size_type m_id;

    void DecrementID(long oldid);
    static LongVec1d& RefCount();
    static std::deque<long>& NextID();

  protected:

  public:
    BranchTag();
    BranchTag(const BranchTag& src);
    BranchTag& operator=(const BranchTag& src);
    virtual ~BranchTag();

    void static BeginBranchIDs(long nids);

    bool operator==(const BranchTag& src) const;
    long ID() const;
};

#endif // BRANCHTAG_H

//____________________________________________________________________________________
