/*
 * Copyright 2017 Google Inc. All Rights Reserved.
 *
 * 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.
 */

#ifndef NB_STD_ALLOCATOR_H_
#define NB_STD_ALLOCATOR_H_

#include <memory>

#include "nb/allocator.h"
#include "starboard/configuration.h"
#include "starboard/types.h"

namespace nb {

// A standard container compatible allocator that delegates allocations to a
// custom allocator. This allows standard containers like vector<> and map<> to
// use custom allocator schemes.
//
// AllocatorT:
//   This is the backing allocator that implements Allocate(...) and
//   Deallocate(...).
//
// Example:
// struct AllocatorImpl {
//   static void* Allocate(size_t n) {
//     return SbMemoryAllocate(n);
//   }
//   // Second argument can be used for accounting, but is otherwise optional.
//   static void Deallocate(void* ptr, size_t n) {
//     SbMemoryDeallocate(ptr);
//   }
// };
//
// typedef std::vector<int, StdAllocator<T, AllocatorImpl> > MyVector;
// MyVector vector;
// ...
template <typename T, typename AllocatorT>
class StdAllocator : public std::allocator<T> {
 public:
  typedef typename std::allocator<T>::pointer pointer;
  typedef typename std::allocator<T>::const_pointer const_pointer;
  typedef typename std::allocator<T>::reference reference;
  typedef typename std::allocator<T>::const_reference const_reference;
  typedef typename std::allocator<T>::size_type size_type;
  typedef typename std::allocator<T>::value_type value_type;
  typedef typename std::allocator<T>::difference_type difference_type;

  StdAllocator() {}

  // Constructor used for rebinding
  template <typename U, typename V>
  StdAllocator(const StdAllocator<U, V>&) {}

  pointer allocate(size_type n,
                   std::allocator<void>::const_pointer hint = NULL) {
    SB_UNREFERENCED_PARAMETER(hint);
    void* ptr = AllocatorT::Allocate(n * sizeof(value_type));
    return static_cast<pointer>(ptr);
  }

  void deallocate(pointer ptr, size_type n) {
    AllocatorT::Deallocate(ptr, n * sizeof(value_type));
  }
  template <typename U>
  struct rebind {
    typedef StdAllocator<U, AllocatorT> other;
  };
};

// A standard container compatible allocator that delegates allocations to a
// custom allocator via a shared pointer. This differs from StdAllocator since
// StdAllocator binds to static functions. This important difference allows
// StdDynamicAllocator to keep memory accounting on a per-instance basis, but
// otherwise is a tad slower, harder to instantiate and produces less readable
// code.
//
// When in doubt, use StdAllocator over StdDynamicAllocator.
//
// Passed in nb::Allocator:
//  Even though nb::Allocator has many functions for alignment, only the two
//  are used within StdDynamicAllocator:
//    void* nb::Allocator::Allocate() -and-
//    void nb::FreeWithSize(void* ptr, size_t optional_size)
//
// Example of Allocator Definition:
//  class MyAllocator : public SimpleAllocator {
//   public:
//    void* Allocate(size_t size) SB_OVERRIDE {
//      return SbMemoryAllocate(size);
//    }
//
//    // Second argument can be used for accounting, but is otherwise optional.
//    void FreeWithSize(void* ptr, size_t optional_size) SB_OVERRIDE {
//      SbMemoryDeallocate(ptr);
//    }
//
//    // ... other functions
//  };
//
// Example of std::vector<int>:
//  typedef StdDynamicAllocator<int> IntAllocator;
//  typedef std::vector<int, IntAllocator> IntVector;
//
//  MyAllocator my_allocator;
//  // Note that IntVector is not default constructible!
//  IntVector int_vector(IntAllocator(&my_allocator));
//
// Example of std::map<int, int>:
//  // Note that maps require std::less() instance to be passed in whenever
//  // a custom allocator is passed in.
//  typedef std::map<int, int, std::less<int>, MyAllocator> IntMap;
//  IntMap int_map(std::less<int>(), /* std::less<int> required pre-C++11 */
//                 IntAllocator(&my_allocator));
template <typename T>
class StdDynamicAllocator : public std::allocator<T> {
 public:
  typedef typename std::allocator<T>::pointer pointer;
  typedef typename std::allocator<T>::const_pointer const_pointer;
  typedef typename std::allocator<T>::reference reference;
  typedef typename std::allocator<T>::const_reference const_reference;
  typedef typename std::allocator<T>::size_type size_type;
  typedef typename std::allocator<T>::value_type value_type;
  typedef typename std::allocator<T>::difference_type difference_type;

  explicit StdDynamicAllocator(Allocator* allocator) : allocator_(allocator) {}
  StdDynamicAllocator(StdDynamicAllocator& std_allocator)
      : allocator_(std_allocator.allocator_) {}

  // Constructor used for rebinding
  template <typename U>
  StdDynamicAllocator(const StdDynamicAllocator<U>& x)
      : allocator_(x.allocator()) {}

  pointer allocate(size_type n,
                   std::allocator<void>::const_pointer hint = NULL) {
    SB_UNREFERENCED_PARAMETER(hint);
    void* ptr = allocator_->Allocate(n * sizeof(value_type));
    return static_cast<pointer>(ptr);
  }

  void deallocate(pointer ptr, size_type n) {
    allocator_->FreeWithSize(ptr, n * sizeof(value_type));
  }
  template <typename U>
  struct rebind {
    typedef StdDynamicAllocator<U> other;
  };

  Allocator* allocator() const { return allocator_; }

 private:
  Allocator* allocator_;
};

}  // namespace nb

#endif  // NB_STD_ALLOCATOR_H_
