Program Listing for File wrap_allocator.hpp

Return to documentation for file (umpire/util/wrap_allocator.hpp)

//////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2016-20, Lawrence Livermore National Security, LLC and Umpire
// project contributors. See the COPYRIGHT file for details.
//
// SPDX-License-Identifier: (MIT)
//////////////////////////////////////////////////////////////////////////////
#ifndef UMPIRE_wrap_allocator_HPP
#define UMPIRE_wrap_allocator_HPP

#include "umpire/Allocator.hpp"
#include "umpire/strategy/AllocationStrategy.hpp"
#include "umpire/strategy/AllocationTracker.hpp"
#include "umpire/strategy/ZeroByteHandler.hpp"
#include "umpire/util/make_unique.hpp"

namespace umpire {
namespace util {

template <typename Base>
std::unique_ptr<Base> do_wrap(std::unique_ptr<Base>&& allocator)
{
  return std::move(allocator);
}

template <typename Base, typename Strategy, typename... Strategies>
std::unique_ptr<Base> do_wrap(std::unique_ptr<Base>&& allocator)
{
  return std::unique_ptr<Base>(new Strategy(
      umpire::util::do_wrap<Base, Strategies...>(std::move(allocator))));
}

template <typename... Strategies>
std::unique_ptr<strategy::AllocationStrategy> wrap_allocator(
    std::unique_ptr<strategy::AllocationStrategy>&& allocator)
{
  return umpire::util::do_wrap<umpire::strategy::AllocationStrategy,
                               Strategies...>(std::move(allocator));
}

template <typename Strategy>
Strategy* unwrap_allocation_strategy(
    strategy::AllocationStrategy* base_strategy)
{
  umpire::strategy::ZeroByteHandler* zero{nullptr};
  umpire::strategy::AllocationTracker* tracker{nullptr};
  Strategy* strategy{nullptr};

  tracker = dynamic_cast<umpire::strategy::AllocationTracker*>(base_strategy);

  if (tracker) {
    zero = dynamic_cast<umpire::strategy::ZeroByteHandler*>(
        tracker->getAllocationStrategy());
  } else {
    zero = dynamic_cast<umpire::strategy::ZeroByteHandler*>(base_strategy);
  }

  if (zero) {
    strategy = dynamic_cast<Strategy*>(zero->getAllocationStrategy());
  } else {
    if (tracker) {
      strategy = dynamic_cast<Strategy*>(tracker->getAllocationStrategy());
    } else {
      strategy = dynamic_cast<Strategy*>(base_strategy);
    }
  }

  if (!strategy) {
    UMPIRE_ERROR("Couldn't unwrap " << base_strategy->getName() << " to "
                                    << typeid(Strategy).name());
  }

  return strategy;
}

template <typename Strategy>
Strategy* unwrap_allocator(Allocator allocator)
{
  return unwrap_allocation_strategy<Strategy>(
      allocator.getAllocationStrategy());
}

} // end of namespace util
} // end of namespace umpire

#endif // UMPIRE_wrap_allocator_HPP