chromium/third_party/s2cellid/src/s2/util/math/vector.h

// 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.
//

// Simple classes to handle vectors in 2D, 3D, and 4D.
//
// Maintainers: Please be mindful of extreme degradations in unoptimized
// performance here.
#ifndef S2_UTIL_MATH_VECTOR_H_
#define S2_UTIL_MATH_VECTOR_H_

#include <algorithm>
#include <cmath>
#include <cstdint>
#include <cstdlib>
#include <iosfwd>
#include <iostream>  // NOLINT(readability/streams)
#include <limits>
#include <type_traits>

#include "base/check_op.h"

template <typename T>
class Vector2;
template <typename T>
class Vector3;
template <typename T>
class Vector4;

namespace util {
namespace math {
namespace internal_vector {

// See http://en.cppreference.com/w/cpp/utility/integer_sequence
// Implemented here to avoid a dependency.
// TODO(user): Reuse std::index_sequence or gtl::IndexSequence.
template <std::size_t... Is>
struct IdxSeq {};
template <std::size_t M, std::size_t... Is>
struct MkIdxSeq : MkIdxSeq<M - 1, M - 1, Is...> {};
MkIdxSeq<0, Is...>;

// CRTP base class for all Vector templates.
template <template <typename> class VecTemplate, typename T, std::size_t N>
class BasicVector {};

// These templates must be defined outside of BasicVector so that the
// template specialization match algorithm must deduce 'a'. See the review
// of cl/119944115.
template <typename K,
          template <typename> class VT2,
          typename T2,
          std::size_t N2>
VT2<T2> operator*(const K& k, const BasicVector<VT2, T2, N2>& a) {}
template <typename K,
          template <typename> class VT2,
          typename T2,
          std::size_t N2>
VT2<T2> operator/(const K& k, const BasicVector<VT2, T2, N2>& a) {}

}  // namespace internal_vector
}  // namespace math
}  // namespace util

// ======================================================================
template <typename T>
class Vector2 : public util::math::internal_vector::BasicVector<Vector2, T, 2> {};

template <typename T>
class Vector3 : public util::math::internal_vector::BasicVector<Vector3, T, 3> {};

template <typename T>
class Vector4 : public util::math::internal_vector::BasicVector<Vector4, T, 4> {};

Vector2_b;
Vector2_i;
Vector2_f;
Vector2_d;

Vector3_b;
Vector3_i;
Vector3_f;
Vector3_d;

Vector4_b;
Vector4_i;
Vector4_f;
Vector4_d;

#endif  // S2_UTIL_MATH_VECTOR_H_