// adds a value, returning false if the given token is not // "reasonable". A reasonable token is one not currently in use, // and if any previously used tokens are available, it must be one // of the previously used ones. If no previously used tokens are // available, it must be the smallest unused token. You'll get // good performance if you never choose a bad token and use the // most recently dropped token. bool add(token_type known_token, T const& value) { if (free_.empty()) { if (known_token == values_.size()) { values_.push_back(value); #ifndef NDEBUG is_free_.push_back(false); #endif return true; } else { return false; } } else { // If a replicand used add(), then it picked the token // from the bock of its free list. So the replicant, the // presumed caller of this function, searches in reverse // order. typename std::vector<token_t>::reverse_iterator p = std::find(free_.rbegin(), free_.rend(), known_token); if (p == free_.rend()) { return false; } if (values_.size() > known_token) { free_.erase(p.base() - 1); values_[known_token] = value; rassert(is_free_[known_token]); #ifndef NDEBUG is_free_[known_token] = false; #endif return true; } else { return false; } } }