http://git-wip-us.apache.org/repos/asf/marmotta/blob/0eb556da/libraries/ostrich/backend/3rdparty/abseil/absl/meta/type_traits_test.cc ---------------------------------------------------------------------- diff --git a/libraries/ostrich/backend/3rdparty/abseil/absl/meta/type_traits_test.cc b/libraries/ostrich/backend/3rdparty/abseil/absl/meta/type_traits_test.cc new file mode 100644 index 0000000..c44d1c5 --- /dev/null +++ b/libraries/ostrich/backend/3rdparty/abseil/absl/meta/type_traits_test.cc @@ -0,0 +1,799 @@ +// Copyright 2017 The Abseil Authors. +// +// 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. + +#include "absl/meta/type_traits.h" + +#include <cstdint> +#include <string> +#include <type_traits> +#include <utility> +#include <vector> + +#include "gtest/gtest.h" + +namespace { + +using ::testing::StaticAssertTypeEq; + +template <class T, class U> +struct simple_pair { + T first; + U second; +}; + +struct Dummy {}; + +TEST(VoidTTest, BasicUsage) { + StaticAssertTypeEq<void, absl::void_t<Dummy>>(); + StaticAssertTypeEq<void, absl::void_t<Dummy, Dummy, Dummy>>(); +} + +TEST(ConjunctionTest, BasicBooleanLogic) { + EXPECT_TRUE(absl::conjunction<>::value); + EXPECT_TRUE(absl::conjunction<std::true_type>::value); + EXPECT_TRUE((absl::conjunction<std::true_type, std::true_type>::value)); + EXPECT_FALSE((absl::conjunction<std::true_type, std::false_type>::value)); + EXPECT_FALSE((absl::conjunction<std::false_type, std::true_type>::value)); + EXPECT_FALSE((absl::conjunction<std::false_type, std::false_type>::value)); +} + +struct MyTrueType { + static constexpr bool value = true; +}; + +struct MyFalseType { + static constexpr bool value = false; +}; + +TEST(ConjunctionTest, ShortCircuiting) { + EXPECT_FALSE( + (absl::conjunction<std::true_type, std::false_type, Dummy>::value)); + EXPECT_TRUE((std::is_base_of<MyFalseType, + absl::conjunction<std::true_type, MyFalseType, + std::false_type>>::value)); + EXPECT_TRUE( + (std::is_base_of<MyTrueType, + absl::conjunction<std::true_type, MyTrueType>>::value)); +} + +TEST(DisjunctionTest, BasicBooleanLogic) { + EXPECT_FALSE(absl::disjunction<>::value); + EXPECT_FALSE(absl::disjunction<std::false_type>::value); + EXPECT_TRUE((absl::disjunction<std::true_type, std::true_type>::value)); + EXPECT_TRUE((absl::disjunction<std::true_type, std::false_type>::value)); + EXPECT_TRUE((absl::disjunction<std::false_type, std::true_type>::value)); + EXPECT_FALSE((absl::disjunction<std::false_type, std::false_type>::value)); +} + +TEST(DisjunctionTest, ShortCircuiting) { + EXPECT_TRUE( + (absl::disjunction<std::false_type, std::true_type, Dummy>::value)); + EXPECT_TRUE(( + std::is_base_of<MyTrueType, absl::disjunction<std::false_type, MyTrueType, + std::true_type>>::value)); + EXPECT_TRUE(( + std::is_base_of<MyFalseType, + absl::disjunction<std::false_type, MyFalseType>>::value)); +} + +TEST(NegationTest, BasicBooleanLogic) { + EXPECT_FALSE(absl::negation<std::true_type>::value); + EXPECT_FALSE(absl::negation<MyTrueType>::value); + EXPECT_TRUE(absl::negation<std::false_type>::value); + EXPECT_TRUE(absl::negation<MyFalseType>::value); +} + +// all member functions are trivial +class Trivial { + int n_; +}; + +struct TrivialDestructor { + ~TrivialDestructor() = default; +}; + +struct NontrivialDestructor { + ~NontrivialDestructor() {} +}; + +struct DeletedDestructor { + ~DeletedDestructor() = delete; +}; + +class TrivialDefaultCtor { + public: + TrivialDefaultCtor() = default; + explicit TrivialDefaultCtor(int n) : n_(n) {} + + private: + int n_; +}; + +class NontrivialDefaultCtor { + public: + NontrivialDefaultCtor() : n_(1) {} + + private: + int n_; +}; + +class DeletedDefaultCtor { + public: + DeletedDefaultCtor() = delete; + explicit DeletedDefaultCtor(int n) : n_(n) {} + + private: + int n_; +}; + +class TrivialCopyCtor { + public: + explicit TrivialCopyCtor(int n) : n_(n) {} + TrivialCopyCtor(const TrivialCopyCtor&) = default; + TrivialCopyCtor& operator=(const TrivialCopyCtor& t) { + n_ = t.n_; + return *this; + } + + private: + int n_; +}; + +class NontrivialCopyCtor { + public: + explicit NontrivialCopyCtor(int n) : n_(n) {} + NontrivialCopyCtor(const NontrivialCopyCtor& t) : n_(t.n_) {} + NontrivialCopyCtor& operator=(const NontrivialCopyCtor&) = default; + + private: + int n_; +}; + +class DeletedCopyCtor { + public: + explicit DeletedCopyCtor(int n) : n_(n) {} + DeletedCopyCtor(const DeletedCopyCtor&) = delete; + DeletedCopyCtor& operator=(const DeletedCopyCtor&) = default; + + private: + int n_; +}; + +class TrivialCopyAssign { + public: + explicit TrivialCopyAssign(int n) : n_(n) {} + TrivialCopyAssign(const TrivialCopyAssign& t) : n_(t.n_) {} + TrivialCopyAssign& operator=(const TrivialCopyAssign& t) = default; + ~TrivialCopyAssign() {} // can have nontrivial destructor + private: + int n_; +}; + +class NontrivialCopyAssign { + public: + explicit NontrivialCopyAssign(int n) : n_(n) {} + NontrivialCopyAssign(const NontrivialCopyAssign&) = default; + NontrivialCopyAssign& operator=(const NontrivialCopyAssign& t) { + n_ = t.n_; + return *this; + } + + private: + int n_; +}; + +class DeletedCopyAssign { + public: + explicit DeletedCopyAssign(int n) : n_(n) {} + DeletedCopyAssign(const DeletedCopyAssign&) = default; + DeletedCopyAssign& operator=(const DeletedCopyAssign&) = delete; + + private: + int n_; +}; + +struct NonCopyable { + NonCopyable() = default; + NonCopyable(const NonCopyable&) = delete; + NonCopyable& operator=(const NonCopyable&) = delete; +}; + +class Base { + public: + virtual ~Base() {} +}; + +// In GCC/Clang, std::is_trivially_constructible requires that the destructor is +// trivial. However, MSVC doesn't require that. This results in different +// behavior when checking is_trivially_constructible on any type with +// nontrivial destructor. Since absl::is_trivially_default_constructible and +// absl::is_trivially_copy_constructible both follows Clang/GCC's interpretation +// and check is_trivially_destructible, it results in inconsistency with +// std::is_trivially_xxx_constructible on MSVC. This macro is used to work +// around this issue in test. In practice, a trivially constructible type +// should also be trivially destructible. +// GCC bug 51452: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51452 +// LWG issue 2116: http://cplusplus.github.io/LWG/lwg-active.html#2116 +#ifndef _MSC_VER +#define ABSL_TRIVIALLY_CONSTRUCTIBLE_VERIFY_TRIVIALLY_DESTRUCTIBLE 1 +#endif + +// Old versions of libc++, around Clang 3.5 to 3.6, consider deleted destructors +// as also being trivial. With the resolution of CWG 1928 and CWG 1734, this +// is no longer considered true and has thus been amended. +// Compiler Explorer: https://godbolt.org/g/zT59ZL +// CWG issue 1734: http://open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html#1734 +// CWG issue 1928: http://open-std.org/JTC1/SC22/WG21/docs/cwg_closed.html#1928 +#if !defined(_LIBCPP_VERSION) || _LIBCPP_VERSION >= 3700 +#define ABSL_TRIVIALLY_DESTRUCTIBLE_CONSIDER_DELETED_DESTRUCTOR_NOT_TRIVIAL 1 +#endif + +// As of the moment, GCC versions >5.1 have a problem compiling for +// std::is_trivially_default_constructible<NontrivialDestructor[10]>, where +// NontrivialDestructor is a struct with a custom nontrivial destructor. Note +// that this problem only occurs for arrays of a known size, so something like +// std::is_trivially_default_constructible<NontrivialDestructor[]> does not +// have any problems. +// Compiler Explorer: https://godbolt.org/g/dXRbdK +// GCC bug 83689: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83689 +#if defined(__clang__) || defined(_MSC_VER) || \ + (defined(__GNUC__) && __GNUC__ < 5) +#define ABSL_GCC_BUG_TRIVIALLY_CONSTRUCTIBLE_ON_ARRAY_OF_NONTRIVIAL 1 +#endif + +TEST(TypeTraitsTest, TestTrivialDestructor) { + // Verify that arithmetic types and pointers have trivial destructors. + EXPECT_TRUE(absl::is_trivially_destructible<bool>::value); + EXPECT_TRUE(absl::is_trivially_destructible<char>::value); + EXPECT_TRUE(absl::is_trivially_destructible<unsigned char>::value); + EXPECT_TRUE(absl::is_trivially_destructible<signed char>::value); + EXPECT_TRUE(absl::is_trivially_destructible<wchar_t>::value); + EXPECT_TRUE(absl::is_trivially_destructible<int>::value); + EXPECT_TRUE(absl::is_trivially_destructible<unsigned int>::value); + EXPECT_TRUE(absl::is_trivially_destructible<int16_t>::value); + EXPECT_TRUE(absl::is_trivially_destructible<uint16_t>::value); + EXPECT_TRUE(absl::is_trivially_destructible<int64_t>::value); + EXPECT_TRUE(absl::is_trivially_destructible<uint64_t>::value); + EXPECT_TRUE(absl::is_trivially_destructible<float>::value); + EXPECT_TRUE(absl::is_trivially_destructible<double>::value); + EXPECT_TRUE(absl::is_trivially_destructible<long double>::value); + EXPECT_TRUE(absl::is_trivially_destructible<std::string*>::value); + EXPECT_TRUE(absl::is_trivially_destructible<Trivial*>::value); + EXPECT_TRUE(absl::is_trivially_destructible<const std::string*>::value); + EXPECT_TRUE(absl::is_trivially_destructible<const Trivial*>::value); + EXPECT_TRUE(absl::is_trivially_destructible<std::string**>::value); + EXPECT_TRUE(absl::is_trivially_destructible<Trivial**>::value); + + // classes with destructors + EXPECT_TRUE(absl::is_trivially_destructible<Trivial>::value); + EXPECT_TRUE(absl::is_trivially_destructible<TrivialDestructor>::value); + + // Verify that types with a nontrivial or deleted destructor + // are marked as such. + EXPECT_FALSE(absl::is_trivially_destructible<NontrivialDestructor>::value); +#ifdef ABSL_TRIVIALLY_DESTRUCTIBLE_CONSIDER_DELETED_DESTRUCTOR_NOT_TRIVIAL + EXPECT_FALSE(absl::is_trivially_destructible<DeletedDestructor>::value); +#endif + + // simple_pair of such types is trivial + EXPECT_TRUE((absl::is_trivially_destructible<simple_pair<int, int>>::value)); + EXPECT_TRUE((absl::is_trivially_destructible< + simple_pair<Trivial, TrivialDestructor>>::value)); + + // Verify that types without trivial destructors are correctly marked as such. + EXPECT_FALSE(absl::is_trivially_destructible<std::string>::value); + EXPECT_FALSE(absl::is_trivially_destructible<std::vector<int>>::value); + + // Verify that simple_pairs of types without trivial destructors + // are not marked as trivial. + EXPECT_FALSE((absl::is_trivially_destructible< + simple_pair<int, std::string>>::value)); + EXPECT_FALSE((absl::is_trivially_destructible< + simple_pair<std::string, int>>::value)); + + // array of such types is trivial + using int10 = int[10]; + EXPECT_TRUE(absl::is_trivially_destructible<int10>::value); + using Trivial10 = Trivial[10]; + EXPECT_TRUE(absl::is_trivially_destructible<Trivial10>::value); + using TrivialDestructor10 = TrivialDestructor[10]; + EXPECT_TRUE(absl::is_trivially_destructible<TrivialDestructor10>::value); + + // Conversely, the opposite also holds. + using NontrivialDestructor10 = NontrivialDestructor[10]; + EXPECT_FALSE(absl::is_trivially_destructible<NontrivialDestructor10>::value); +} + +TEST(TypeTraitsTest, TestTrivialDefaultCtor) { + // arithmetic types and pointers have trivial default constructors. + EXPECT_TRUE(absl::is_trivially_default_constructible<bool>::value); + EXPECT_TRUE(absl::is_trivially_default_constructible<char>::value); + EXPECT_TRUE(absl::is_trivially_default_constructible<unsigned char>::value); + EXPECT_TRUE(absl::is_trivially_default_constructible<signed char>::value); + EXPECT_TRUE(absl::is_trivially_default_constructible<wchar_t>::value); + EXPECT_TRUE(absl::is_trivially_default_constructible<int>::value); + EXPECT_TRUE(absl::is_trivially_default_constructible<unsigned int>::value); + EXPECT_TRUE(absl::is_trivially_default_constructible<int16_t>::value); + EXPECT_TRUE(absl::is_trivially_default_constructible<uint16_t>::value); + EXPECT_TRUE(absl::is_trivially_default_constructible<int64_t>::value); + EXPECT_TRUE(absl::is_trivially_default_constructible<uint64_t>::value); + EXPECT_TRUE(absl::is_trivially_default_constructible<float>::value); + EXPECT_TRUE(absl::is_trivially_default_constructible<double>::value); + EXPECT_TRUE(absl::is_trivially_default_constructible<long double>::value); + EXPECT_TRUE(absl::is_trivially_default_constructible<std::string*>::value); + EXPECT_TRUE(absl::is_trivially_default_constructible<Trivial*>::value); + EXPECT_TRUE( + absl::is_trivially_default_constructible<const std::string*>::value); + EXPECT_TRUE(absl::is_trivially_default_constructible<const Trivial*>::value); + EXPECT_TRUE(absl::is_trivially_default_constructible<std::string**>::value); + EXPECT_TRUE(absl::is_trivially_default_constructible<Trivial**>::value); + + // types with compiler generated default ctors + EXPECT_TRUE(absl::is_trivially_default_constructible<Trivial>::value); + EXPECT_TRUE( + absl::is_trivially_default_constructible<TrivialDefaultCtor>::value); + + // Verify that types without them are not. + EXPECT_FALSE( + absl::is_trivially_default_constructible<NontrivialDefaultCtor>::value); + EXPECT_FALSE( + absl::is_trivially_default_constructible<DeletedDefaultCtor>::value); + +#ifdef ABSL_TRIVIALLY_CONSTRUCTIBLE_VERIFY_TRIVIALLY_DESTRUCTIBLE + // types with nontrivial destructor are nontrivial + EXPECT_FALSE( + absl::is_trivially_default_constructible<NontrivialDestructor>::value); +#endif + + // types with vtables + EXPECT_FALSE(absl::is_trivially_default_constructible<Base>::value); + + // Verify that simple_pair has trivial constructors where applicable. + EXPECT_TRUE((absl::is_trivially_default_constructible< + simple_pair<int, char*>>::value)); + EXPECT_TRUE((absl::is_trivially_default_constructible< + simple_pair<int, Trivial>>::value)); + EXPECT_TRUE((absl::is_trivially_default_constructible< + simple_pair<int, TrivialDefaultCtor>>::value)); + + // Verify that types without trivial constructors are + // correctly marked as such. + EXPECT_FALSE(absl::is_trivially_default_constructible<std::string>::value); + EXPECT_FALSE( + absl::is_trivially_default_constructible<std::vector<int>>::value); + + // Verify that simple_pairs of types without trivial constructors + // are not marked as trivial. + EXPECT_FALSE((absl::is_trivially_default_constructible< + simple_pair<int, std::string>>::value)); + EXPECT_FALSE((absl::is_trivially_default_constructible< + simple_pair<std::string, int>>::value)); + + // Verify that arrays of such types are trivially default constructible + using int10 = int[10]; + EXPECT_TRUE(absl::is_trivially_default_constructible<int10>::value); + using Trivial10 = Trivial[10]; + EXPECT_TRUE(absl::is_trivially_default_constructible<Trivial10>::value); + using TrivialDefaultCtor10 = TrivialDefaultCtor[10]; + EXPECT_TRUE( + absl::is_trivially_default_constructible<TrivialDefaultCtor10>::value); + + // Conversely, the opposite also holds. +#ifdef ABSL_GCC_BUG_TRIVIALLY_CONSTRUCTIBLE_ON_ARRAY_OF_NONTRIVIAL + using NontrivialDefaultCtor10 = NontrivialDefaultCtor[10]; + EXPECT_FALSE( + absl::is_trivially_default_constructible<NontrivialDefaultCtor10>::value); +#endif +} + +TEST(TypeTraitsTest, TestTrivialCopyCtor) { + // Verify that arithmetic types and pointers have trivial copy + // constructors. + EXPECT_TRUE(absl::is_trivially_copy_constructible<bool>::value); + EXPECT_TRUE(absl::is_trivially_copy_constructible<char>::value); + EXPECT_TRUE(absl::is_trivially_copy_constructible<unsigned char>::value); + EXPECT_TRUE(absl::is_trivially_copy_constructible<signed char>::value); + EXPECT_TRUE(absl::is_trivially_copy_constructible<wchar_t>::value); + EXPECT_TRUE(absl::is_trivially_copy_constructible<int>::value); + EXPECT_TRUE(absl::is_trivially_copy_constructible<unsigned int>::value); + EXPECT_TRUE(absl::is_trivially_copy_constructible<int16_t>::value); + EXPECT_TRUE(absl::is_trivially_copy_constructible<uint16_t>::value); + EXPECT_TRUE(absl::is_trivially_copy_constructible<int64_t>::value); + EXPECT_TRUE(absl::is_trivially_copy_constructible<uint64_t>::value); + EXPECT_TRUE(absl::is_trivially_copy_constructible<float>::value); + EXPECT_TRUE(absl::is_trivially_copy_constructible<double>::value); + EXPECT_TRUE(absl::is_trivially_copy_constructible<long double>::value); + EXPECT_TRUE(absl::is_trivially_copy_constructible<std::string*>::value); + EXPECT_TRUE(absl::is_trivially_copy_constructible<Trivial*>::value); + EXPECT_TRUE(absl::is_trivially_copy_constructible<const std::string*>::value); + EXPECT_TRUE(absl::is_trivially_copy_constructible<const Trivial*>::value); + EXPECT_TRUE(absl::is_trivially_copy_constructible<std::string**>::value); + EXPECT_TRUE(absl::is_trivially_copy_constructible<Trivial**>::value); + + // types with compiler generated copy ctors + EXPECT_TRUE(absl::is_trivially_copy_constructible<Trivial>::value); + EXPECT_TRUE(absl::is_trivially_copy_constructible<TrivialCopyCtor>::value); + + // Verify that types without them (i.e. nontrivial or deleted) are not. + EXPECT_FALSE( + absl::is_trivially_copy_constructible<NontrivialCopyCtor>::value); + EXPECT_FALSE(absl::is_trivially_copy_constructible<DeletedCopyCtor>::value); + EXPECT_FALSE( + absl::is_trivially_copy_constructible<NonCopyable>::value); + +#ifdef ABSL_TRIVIALLY_CONSTRUCTIBLE_VERIFY_TRIVIALLY_DESTRUCTIBLE + // type with nontrivial destructor are nontrivial copy construbtible + EXPECT_FALSE( + absl::is_trivially_copy_constructible<NontrivialDestructor>::value); +#endif + + // types with vtables + EXPECT_FALSE(absl::is_trivially_copy_constructible<Base>::value); + + // Verify that simple_pair of such types is trivially copy constructible + EXPECT_TRUE( + (absl::is_trivially_copy_constructible<simple_pair<int, char*>>::value)); + EXPECT_TRUE(( + absl::is_trivially_copy_constructible<simple_pair<int, Trivial>>::value)); + EXPECT_TRUE((absl::is_trivially_copy_constructible< + simple_pair<int, TrivialCopyCtor>>::value)); + + // Verify that types without trivial copy constructors are + // correctly marked as such. + EXPECT_FALSE(absl::is_trivially_copy_constructible<std::string>::value); + EXPECT_FALSE(absl::is_trivially_copy_constructible<std::vector<int>>::value); + + // Verify that simple_pairs of types without trivial copy constructors + // are not marked as trivial. + EXPECT_FALSE((absl::is_trivially_copy_constructible< + simple_pair<int, std::string>>::value)); + EXPECT_FALSE((absl::is_trivially_copy_constructible< + simple_pair<std::string, int>>::value)); + + // Verify that arrays are not + using int10 = int[10]; + EXPECT_FALSE(absl::is_trivially_copy_constructible<int10>::value); +} + +TEST(TypeTraitsTest, TestTrivialCopyAssign) { + // Verify that arithmetic types and pointers have trivial copy + // assignment operators. + EXPECT_TRUE(absl::is_trivially_copy_assignable<bool>::value); + EXPECT_TRUE(absl::is_trivially_copy_assignable<char>::value); + EXPECT_TRUE(absl::is_trivially_copy_assignable<unsigned char>::value); + EXPECT_TRUE(absl::is_trivially_copy_assignable<signed char>::value); + EXPECT_TRUE(absl::is_trivially_copy_assignable<wchar_t>::value); + EXPECT_TRUE(absl::is_trivially_copy_assignable<int>::value); + EXPECT_TRUE(absl::is_trivially_copy_assignable<unsigned int>::value); + EXPECT_TRUE(absl::is_trivially_copy_assignable<int16_t>::value); + EXPECT_TRUE(absl::is_trivially_copy_assignable<uint16_t>::value); + EXPECT_TRUE(absl::is_trivially_copy_assignable<int64_t>::value); + EXPECT_TRUE(absl::is_trivially_copy_assignable<uint64_t>::value); + EXPECT_TRUE(absl::is_trivially_copy_assignable<float>::value); + EXPECT_TRUE(absl::is_trivially_copy_assignable<double>::value); + EXPECT_TRUE(absl::is_trivially_copy_assignable<long double>::value); + EXPECT_TRUE(absl::is_trivially_copy_assignable<std::string*>::value); + EXPECT_TRUE(absl::is_trivially_copy_assignable<Trivial*>::value); + EXPECT_TRUE(absl::is_trivially_copy_assignable<const std::string*>::value); + EXPECT_TRUE(absl::is_trivially_copy_assignable<const Trivial*>::value); + EXPECT_TRUE(absl::is_trivially_copy_assignable<std::string**>::value); + EXPECT_TRUE(absl::is_trivially_copy_assignable<Trivial**>::value); + + // const qualified types are not assignable + EXPECT_FALSE(absl::is_trivially_copy_assignable<const int>::value); + + // types with compiler generated copy assignment + EXPECT_TRUE(absl::is_trivially_copy_assignable<Trivial>::value); + EXPECT_TRUE(absl::is_trivially_copy_assignable<TrivialCopyAssign>::value); + + // Verify that types without them (i.e. nontrivial or deleted) are not. + EXPECT_FALSE(absl::is_trivially_copy_assignable<NontrivialCopyAssign>::value); + EXPECT_FALSE(absl::is_trivially_copy_assignable<DeletedCopyAssign>::value); + EXPECT_FALSE(absl::is_trivially_copy_assignable<NonCopyable>::value); + + // types with vtables + EXPECT_FALSE(absl::is_trivially_copy_assignable<Base>::value); + + // Verify that simple_pair is trivially assignable + EXPECT_TRUE( + (absl::is_trivially_copy_assignable<simple_pair<int, char*>>::value)); + EXPECT_TRUE( + (absl::is_trivially_copy_assignable<simple_pair<int, Trivial>>::value)); + EXPECT_TRUE((absl::is_trivially_copy_assignable< + simple_pair<int, TrivialCopyAssign>>::value)); + + // Verify that types not trivially copy assignable are + // correctly marked as such. + EXPECT_FALSE(absl::is_trivially_copy_assignable<std::string>::value); + EXPECT_FALSE(absl::is_trivially_copy_assignable<std::vector<int>>::value); + + // Verify that simple_pairs of types not trivially copy assignable + // are not marked as trivial. + EXPECT_FALSE((absl::is_trivially_copy_assignable< + simple_pair<int, std::string>>::value)); + EXPECT_FALSE((absl::is_trivially_copy_assignable< + simple_pair<std::string, int>>::value)); + + // Verify that arrays are not trivially copy assignable + using int10 = int[10]; + EXPECT_FALSE(absl::is_trivially_copy_assignable<int10>::value); +} + +#define ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(trait_name, ...) \ + EXPECT_TRUE((std::is_same<typename std::trait_name<__VA_ARGS__>::type, \ + absl::trait_name##_t<__VA_ARGS__>>::value)) + +TEST(TypeTraitsTest, TestRemoveCVAliases) { + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_cv, int); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_cv, const int); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_cv, volatile int); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_cv, const volatile int); + + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_const, int); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_const, const int); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_const, volatile int); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_const, const volatile int); + + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_volatile, int); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_volatile, const int); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_volatile, volatile int); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_volatile, const volatile int); +} + +TEST(TypeTraitsTest, TestAddCVAliases) { + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_cv, int); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_cv, const int); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_cv, volatile int); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_cv, const volatile int); + + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_const, int); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_const, const int); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_const, volatile int); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_const, const volatile int); + + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_volatile, int); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_volatile, const int); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_volatile, volatile int); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_volatile, const volatile int); +} + +TEST(TypeTraitsTest, TestReferenceAliases) { + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_reference, int); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_reference, volatile int); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_reference, int&); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_reference, volatile int&); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_reference, int&&); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_reference, volatile int&&); + + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_lvalue_reference, int); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_lvalue_reference, volatile int); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_lvalue_reference, int&); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_lvalue_reference, volatile int&); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_lvalue_reference, int&&); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_lvalue_reference, volatile int&&); + + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_rvalue_reference, int); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_rvalue_reference, volatile int); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_rvalue_reference, int&); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_rvalue_reference, volatile int&); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_rvalue_reference, int&&); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_rvalue_reference, volatile int&&); +} + +TEST(TypeTraitsTest, TestPointerAliases) { + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_pointer, int*); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_pointer, volatile int*); + + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_pointer, int); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_pointer, volatile int); +} + +TEST(TypeTraitsTest, TestSignednessAliases) { + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(make_signed, int); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(make_signed, volatile int); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(make_signed, unsigned); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(make_signed, volatile unsigned); + + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(make_unsigned, int); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(make_unsigned, volatile int); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(make_unsigned, unsigned); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(make_unsigned, volatile unsigned); +} + +TEST(TypeTraitsTest, TestExtentAliases) { + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_extent, int[]); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_extent, int[1]); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_extent, int[1][1]); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_extent, int[][1]); + + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_all_extents, int[]); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_all_extents, int[1]); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_all_extents, int[1][1]); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_all_extents, int[][1]); +} + +TEST(TypeTraitsTest, TestAlignedStorageAlias) { + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 1); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 2); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 3); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 4); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 5); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 6); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 7); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 8); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 9); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 10); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 11); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 12); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 13); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 14); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 15); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 16); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 17); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 18); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 19); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 20); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 21); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 22); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 23); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 24); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 25); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 26); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 27); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 28); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 29); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 30); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 31); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 32); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 33); + + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 1, 128); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 2, 128); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 3, 128); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 4, 128); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 5, 128); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 6, 128); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 7, 128); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 8, 128); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 9, 128); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 10, 128); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 11, 128); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 12, 128); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 13, 128); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 14, 128); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 15, 128); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 16, 128); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 17, 128); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 18, 128); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 19, 128); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 20, 128); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 21, 128); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 22, 128); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 23, 128); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 24, 128); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 25, 128); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 26, 128); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 27, 128); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 28, 128); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 29, 128); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 30, 128); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 31, 128); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 32, 128); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 33, 128); +} + +TEST(TypeTraitsTest, TestDecay) { + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(decay, int); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(decay, const int); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(decay, volatile int); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(decay, const volatile int); + + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(decay, int&); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(decay, const int&); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(decay, volatile int&); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(decay, const volatile int&); + + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(decay, int&); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(decay, const int&); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(decay, volatile int&); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(decay, const volatile int&); + + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(decay, int[1]); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(decay, int[1][1]); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(decay, int[][1]); + + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(decay, int()); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(decay, int(float)); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(decay, int(char, ...)); +} + +struct TypeA {}; +struct TypeB {}; +struct TypeC {}; +struct TypeD {}; + +template <typename T> +struct Wrap {}; + +enum class TypeEnum { A, B, C, D }; + +struct GetTypeT { + template <typename T, + absl::enable_if_t<std::is_same<T, TypeA>::value, int> = 0> + TypeEnum operator()(Wrap<T>) const { + return TypeEnum::A; + } + + template <typename T, + absl::enable_if_t<std::is_same<T, TypeB>::value, int> = 0> + TypeEnum operator()(Wrap<T>) const { + return TypeEnum::B; + } + + template <typename T, + absl::enable_if_t<std::is_same<T, TypeC>::value, int> = 0> + TypeEnum operator()(Wrap<T>) const { + return TypeEnum::C; + } + + // NOTE: TypeD is intentionally not handled +} constexpr GetType = {}; + +TEST(TypeTraitsTest, TestEnableIf) { + EXPECT_EQ(TypeEnum::A, GetType(Wrap<TypeA>())); + EXPECT_EQ(TypeEnum::B, GetType(Wrap<TypeB>())); + EXPECT_EQ(TypeEnum::C, GetType(Wrap<TypeC>())); +} + +TEST(TypeTraitsTest, TestConditional) { + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(conditional, true, int, char); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(conditional, false, int, char); +} + +// TODO(calabrese) Check with specialized std::common_type +TEST(TypeTraitsTest, TestCommonType) { + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(common_type, int); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(common_type, int, char); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(common_type, int, char, int); + + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(common_type, int&); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(common_type, int, char&); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(common_type, int, char, int&); +} + +TEST(TypeTraitsTest, TestUnderlyingType) { + enum class enum_char : char {}; + enum class enum_long_long : long long {}; // NOLINT(runtime/int) + + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(underlying_type, enum_char); + ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(underlying_type, enum_long_long); +} + +struct GetTypeExtT { + template <typename T> + absl::result_of_t<const GetTypeT&(T)> operator()(T&& arg) const { + return GetType(std::forward<T>(arg)); + } + + TypeEnum operator()(Wrap<TypeD>) const { return TypeEnum::D; } +} constexpr GetTypeExt = {}; + +TEST(TypeTraitsTest, TestResultOf) { + EXPECT_EQ(TypeEnum::A, GetTypeExt(Wrap<TypeA>())); + EXPECT_EQ(TypeEnum::B, GetTypeExt(Wrap<TypeB>())); + EXPECT_EQ(TypeEnum::C, GetTypeExt(Wrap<TypeC>())); + EXPECT_EQ(TypeEnum::D, GetTypeExt(Wrap<TypeD>())); +} + +} // namespace
http://git-wip-us.apache.org/repos/asf/marmotta/blob/0eb556da/libraries/ostrich/backend/3rdparty/abseil/absl/numeric/BUILD.bazel ---------------------------------------------------------------------- diff --git a/libraries/ostrich/backend/3rdparty/abseil/absl/numeric/BUILD.bazel b/libraries/ostrich/backend/3rdparty/abseil/absl/numeric/BUILD.bazel new file mode 100644 index 0000000..4a24a87 --- /dev/null +++ b/libraries/ostrich/backend/3rdparty/abseil/absl/numeric/BUILD.bazel @@ -0,0 +1,41 @@ +load( + "//absl:copts.bzl", + "ABSL_DEFAULT_COPTS", + "ABSL_TEST_COPTS", +) + +package(default_visibility = ["//visibility:public"]) + +licenses(["notice"]) # Apache 2.0 + +cc_library( + name = "int128", + srcs = [ + "int128.cc", + "int128_have_intrinsic.inc", + "int128_no_intrinsic.inc", + ], + hdrs = ["int128.h"], + copts = ABSL_DEFAULT_COPTS, + deps = [ + "//absl/base:config", + "//absl/base:core_headers", + ], +) + +cc_test( + name = "int128_test", + size = "small", + srcs = [ + "int128_stream_test.cc", + "int128_test.cc", + ], + copts = ABSL_TEST_COPTS, + deps = [ + ":int128", + "//absl/base", + "//absl/base:core_headers", + "//absl/meta:type_traits", + "@com_google_googletest//:gtest_main", + ], +) http://git-wip-us.apache.org/repos/asf/marmotta/blob/0eb556da/libraries/ostrich/backend/3rdparty/abseil/absl/numeric/CMakeLists.txt ---------------------------------------------------------------------- diff --git a/libraries/ostrich/backend/3rdparty/abseil/absl/numeric/CMakeLists.txt b/libraries/ostrich/backend/3rdparty/abseil/absl/numeric/CMakeLists.txt new file mode 100644 index 0000000..3360b2e --- /dev/null +++ b/libraries/ostrich/backend/3rdparty/abseil/absl/numeric/CMakeLists.txt @@ -0,0 +1,62 @@ +# +# Copyright 2017 The Abseil Authors. +# +# 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. +# + +list(APPEND NUMERIC_PUBLIC_HEADERS + "int128.h" +) + + +# library 128 +list(APPEND INT128_SRC + "int128.cc" + ${NUMERIC_PUBLIC_HEADERS} +) +absl_library( + TARGET + absl_int128 + SOURCES + ${INT128_SRC} + PUBLIC_LIBRARIES + ${INT128_PUBLIC_LIBRARIES} + EXPORT_NAME + int128 +) + + +absl_header_library( + TARGET + absl_numeric + PUBLIC_LIBRARIES + absl::int128 + EXPORT_NAME + numeric +) + +# test int128_test +set(INT128_TEST_SRC "int128_test.cc") +set(INT128_TEST_PUBLIC_LIBRARIES absl::numeric absl::base) + +absl_test( + TARGET + int128_test + SOURCES + ${INT128_TEST_SRC} + PUBLIC_LIBRARIES + ${INT128_TEST_PUBLIC_LIBRARIES} +) + + + http://git-wip-us.apache.org/repos/asf/marmotta/blob/0eb556da/libraries/ostrich/backend/3rdparty/abseil/absl/numeric/int128.cc ---------------------------------------------------------------------- diff --git a/libraries/ostrich/backend/3rdparty/abseil/absl/numeric/int128.cc b/libraries/ostrich/backend/3rdparty/abseil/absl/numeric/int128.cc new file mode 100644 index 0000000..3688e5e --- /dev/null +++ b/libraries/ostrich/backend/3rdparty/abseil/absl/numeric/int128.cc @@ -0,0 +1,225 @@ +// Copyright 2017 The Abseil Authors. +// +// 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. + +#include "absl/numeric/int128.h" + +#include <stddef.h> +#include <cassert> +#include <iomanip> +#include <iostream> // NOLINT(readability/streams) +#include <sstream> +#include <string> +#include <type_traits> + +namespace absl { + +const uint128 kuint128max = MakeUint128(std::numeric_limits<uint64_t>::max(), + std::numeric_limits<uint64_t>::max()); + +namespace { + +// Returns the 0-based position of the last set bit (i.e., most significant bit) +// in the given uint64_t. The argument may not be 0. +// +// For example: +// Given: 5 (decimal) == 101 (binary) +// Returns: 2 +#define STEP(T, n, pos, sh) \ + do { \ + if ((n) >= (static_cast<T>(1) << (sh))) { \ + (n) = (n) >> (sh); \ + (pos) |= (sh); \ + } \ + } while (0) +static inline int Fls64(uint64_t n) { + assert(n != 0); + int pos = 0; + STEP(uint64_t, n, pos, 0x20); + uint32_t n32 = static_cast<uint32_t>(n); + STEP(uint32_t, n32, pos, 0x10); + STEP(uint32_t, n32, pos, 0x08); + STEP(uint32_t, n32, pos, 0x04); + return pos + ((uint64_t{0x3333333322221100} >> (n32 << 2)) & 0x3); +} +#undef STEP + +// Like Fls64() above, but returns the 0-based position of the last set bit +// (i.e., most significant bit) in the given uint128. The argument may not be 0. +static inline int Fls128(uint128 n) { + if (uint64_t hi = Uint128High64(n)) { + return Fls64(hi) + 64; + } + return Fls64(Uint128Low64(n)); +} + +// Long division/modulo for uint128 implemented using the shift-subtract +// division algorithm adapted from: +// http://stackoverflow.com/questions/5386377/division-without-using +void DivModImpl(uint128 dividend, uint128 divisor, uint128* quotient_ret, + uint128* remainder_ret) { + assert(divisor != 0); + + if (divisor > dividend) { + *quotient_ret = 0; + *remainder_ret = dividend; + return; + } + + if (divisor == dividend) { + *quotient_ret = 1; + *remainder_ret = 0; + return; + } + + uint128 denominator = divisor; + uint128 quotient = 0; + + // Left aligns the MSB of the denominator and the dividend. + const int shift = Fls128(dividend) - Fls128(denominator); + denominator <<= shift; + + // Uses shift-subtract algorithm to divide dividend by denominator. The + // remainder will be left in dividend. + for (int i = 0; i <= shift; ++i) { + quotient <<= 1; + if (dividend >= denominator) { + dividend -= denominator; + quotient |= 1; + } + denominator >>= 1; + } + + *quotient_ret = quotient; + *remainder_ret = dividend; +} + +template <typename T> +uint128 MakeUint128FromFloat(T v) { + static_assert(std::is_floating_point<T>::value, ""); + + // Rounding behavior is towards zero, same as for built-in types. + + // Undefined behavior if v is NaN or cannot fit into uint128. + assert(std::isfinite(v) && v > -1 && + (std::numeric_limits<T>::max_exponent <= 128 || + v < std::ldexp(static_cast<T>(1), 128))); + + if (v >= std::ldexp(static_cast<T>(1), 64)) { + uint64_t hi = static_cast<uint64_t>(std::ldexp(v, -64)); + uint64_t lo = static_cast<uint64_t>(v - std::ldexp(static_cast<T>(hi), 64)); + return MakeUint128(hi, lo); + } + + return MakeUint128(0, static_cast<uint64_t>(v)); +} +} // namespace + +uint128::uint128(float v) : uint128(MakeUint128FromFloat(v)) {} +uint128::uint128(double v) : uint128(MakeUint128FromFloat(v)) {} +uint128::uint128(long double v) : uint128(MakeUint128FromFloat(v)) {} + +uint128 operator/(uint128 lhs, uint128 rhs) { +#if defined(ABSL_HAVE_INTRINSIC_INT128) + return static_cast<unsigned __int128>(lhs) / + static_cast<unsigned __int128>(rhs); +#else // ABSL_HAVE_INTRINSIC_INT128 + uint128 quotient = 0; + uint128 remainder = 0; + DivModImpl(lhs, rhs, "ient, &remainder); + return quotient; +#endif // ABSL_HAVE_INTRINSIC_INT128 +} +uint128 operator%(uint128 lhs, uint128 rhs) { +#if defined(ABSL_HAVE_INTRINSIC_INT128) + return static_cast<unsigned __int128>(lhs) % + static_cast<unsigned __int128>(rhs); +#else // ABSL_HAVE_INTRINSIC_INT128 + uint128 quotient = 0; + uint128 remainder = 0; + DivModImpl(lhs, rhs, "ient, &remainder); + return remainder; +#endif // ABSL_HAVE_INTRINSIC_INT128 +} + +namespace { + +std::string Uint128ToFormattedString(uint128 v, std::ios_base::fmtflags flags) { + // Select a divisor which is the largest power of the base < 2^64. + uint128 div; + int div_base_log; + switch (flags & std::ios::basefield) { + case std::ios::hex: + div = 0x1000000000000000; // 16^15 + div_base_log = 15; + break; + case std::ios::oct: + div = 01000000000000000000000; // 8^21 + div_base_log = 21; + break; + default: // std::ios::dec + div = 10000000000000000000u; // 10^19 + div_base_log = 19; + break; + } + + // Now piece together the uint128 representation from three chunks of the + // original value, each less than "div" and therefore representable as a + // uint64_t. + std::ostringstream os; + std::ios_base::fmtflags copy_mask = + std::ios::basefield | std::ios::showbase | std::ios::uppercase; + os.setf(flags & copy_mask, copy_mask); + uint128 high = v; + uint128 low; + DivModImpl(high, div, &high, &low); + uint128 mid; + DivModImpl(high, div, &high, &mid); + if (Uint128Low64(high) != 0) { + os << Uint128Low64(high); + os << std::noshowbase << std::setfill('0') << std::setw(div_base_log); + os << Uint128Low64(mid); + os << std::setw(div_base_log); + } else if (Uint128Low64(mid) != 0) { + os << Uint128Low64(mid); + os << std::noshowbase << std::setfill('0') << std::setw(div_base_log); + } + os << Uint128Low64(low); + return os.str(); +} + +} // namespace + +std::ostream& operator<<(std::ostream& os, uint128 v) { + std::ios_base::fmtflags flags = os.flags(); + std::string rep = Uint128ToFormattedString(v, flags); + + // Add the requisite padding. + std::streamsize width = os.width(0); + if (static_cast<size_t>(width) > rep.size()) { + std::ios::fmtflags adjustfield = flags & std::ios::adjustfield; + if (adjustfield == std::ios::left) { + rep.append(width - rep.size(), os.fill()); + } else if (adjustfield == std::ios::internal && + (flags & std::ios::showbase) && + (flags & std::ios::basefield) == std::ios::hex && v != 0) { + rep.insert(2, width - rep.size(), os.fill()); + } else { + rep.insert(0, width - rep.size(), os.fill()); + } + } + + return os << rep; +} + +} // namespace absl http://git-wip-us.apache.org/repos/asf/marmotta/blob/0eb556da/libraries/ostrich/backend/3rdparty/abseil/absl/numeric/int128.h ---------------------------------------------------------------------- diff --git a/libraries/ostrich/backend/3rdparty/abseil/absl/numeric/int128.h b/libraries/ostrich/backend/3rdparty/abseil/absl/numeric/int128.h new file mode 100644 index 0000000..bc7dbb4 --- /dev/null +++ b/libraries/ostrich/backend/3rdparty/abseil/absl/numeric/int128.h @@ -0,0 +1,656 @@ +// +// Copyright 2017 The Abseil Authors. +// +// 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. +// +// ----------------------------------------------------------------------------- +// File: int128.h +// ----------------------------------------------------------------------------- +// +// This header file defines 128-bit integer types. +// +// Currently, this file defines `uint128`, an unsigned 128-bit integer; a signed +// 128-bit integer is forthcoming. + +#ifndef ABSL_NUMERIC_INT128_H_ +#define ABSL_NUMERIC_INT128_H_ + +#include <cassert> +#include <cmath> +#include <cstdint> +#include <cstring> +#include <iosfwd> +#include <limits> + +#include "absl/base/config.h" +#include "absl/base/macros.h" +#include "absl/base/port.h" + +namespace absl { + + +// uint128 +// +// An unsigned 128-bit integer type. The API is meant to mimic an intrinsic type +// as closely as is practical, including exhibiting undefined behavior in +// analogous cases (e.g. division by zero). This type is intended to be a +// drop-in replacement once C++ supports an intrinsic `uint128_t` type; when +// that occurs, existing well-behaved uses of `uint128` will continue to work +// using that new type. +// +// Note: code written with this type will continue to compile once `uint128_t` +// is introduced, provided the replacement helper functions +// `Uint128(Low|High)64()` and `MakeUint128()` are made. +// +// A `uint128` supports the following: +// +// * Implicit construction from integral types +// * Explicit conversion to integral types +// +// Additionally, if your compiler supports `__int128`, `uint128` is +// interoperable with that type. (Abseil checks for this compatibility through +// the `ABSL_HAVE_INTRINSIC_INT128` macro.) +// +// However, a `uint128` differs from intrinsic integral types in the following +// ways: +// +// * Errors on implicit conversions that do not preserve value (such as +// loss of precision when converting to float values). +// * Requires explicit construction from and conversion to floating point +// types. +// * Conversion to integral types requires an explicit static_cast() to +// mimic use of the `-Wnarrowing` compiler flag. +// * The alignment requirement of `uint128` may differ from that of an +// intrinsic 128-bit integer type depending on platform and build +// configuration. +// +// Example: +// +// float y = absl::Uint128Max(); // Error. uint128 cannot be implicitly +// // converted to float. +// +// absl::uint128 v; +// uint64_t i = v; // Error +// uint64_t i = static_cast<uint64_t>(v); // OK +// +class +#if defined(ABSL_HAVE_INTRINSIC_INT128) + alignas(unsigned __int128) +#endif // ABSL_HAVE_INTRINSIC_INT128 + uint128 { + public: + uint128() = default; + + // Constructors from arithmetic types + constexpr uint128(int v); // NOLINT(runtime/explicit) + constexpr uint128(unsigned int v); // NOLINT(runtime/explicit) + constexpr uint128(long v); // NOLINT(runtime/int) + constexpr uint128(unsigned long v); // NOLINT(runtime/int) + constexpr uint128(long long v); // NOLINT(runtime/int) + constexpr uint128(unsigned long long v); // NOLINT(runtime/int) +#ifdef ABSL_HAVE_INTRINSIC_INT128 + constexpr uint128(__int128 v); // NOLINT(runtime/explicit) + constexpr uint128(unsigned __int128 v); // NOLINT(runtime/explicit) +#endif // ABSL_HAVE_INTRINSIC_INT128 + explicit uint128(float v); + explicit uint128(double v); + explicit uint128(long double v); + + // Assignment operators from arithmetic types + uint128& operator=(int v); + uint128& operator=(unsigned int v); + uint128& operator=(long v); // NOLINT(runtime/int) + uint128& operator=(unsigned long v); // NOLINT(runtime/int) + uint128& operator=(long long v); // NOLINT(runtime/int) + uint128& operator=(unsigned long long v); // NOLINT(runtime/int) +#ifdef ABSL_HAVE_INTRINSIC_INT128 + uint128& operator=(__int128 v); + uint128& operator=(unsigned __int128 v); +#endif // ABSL_HAVE_INTRINSIC_INT128 + + // Conversion operators to other arithmetic types + constexpr explicit operator bool() const; + constexpr explicit operator char() const; + constexpr explicit operator signed char() const; + constexpr explicit operator unsigned char() const; + constexpr explicit operator char16_t() const; + constexpr explicit operator char32_t() const; + constexpr explicit operator wchar_t() const; + constexpr explicit operator short() const; // NOLINT(runtime/int) + // NOLINTNEXTLINE(runtime/int) + constexpr explicit operator unsigned short() const; + constexpr explicit operator int() const; + constexpr explicit operator unsigned int() const; + constexpr explicit operator long() const; // NOLINT(runtime/int) + // NOLINTNEXTLINE(runtime/int) + constexpr explicit operator unsigned long() const; + // NOLINTNEXTLINE(runtime/int) + constexpr explicit operator long long() const; + // NOLINTNEXTLINE(runtime/int) + constexpr explicit operator unsigned long long() const; +#ifdef ABSL_HAVE_INTRINSIC_INT128 + constexpr explicit operator __int128() const; + constexpr explicit operator unsigned __int128() const; +#endif // ABSL_HAVE_INTRINSIC_INT128 + explicit operator float() const; + explicit operator double() const; + explicit operator long double() const; + + // Trivial copy constructor, assignment operator and destructor. + + // Arithmetic operators. + uint128& operator+=(uint128 other); + uint128& operator-=(uint128 other); + uint128& operator*=(uint128 other); + // Long division/modulo for uint128. + uint128& operator/=(uint128 other); + uint128& operator%=(uint128 other); + uint128 operator++(int); + uint128 operator--(int); + uint128& operator<<=(int); + uint128& operator>>=(int); + uint128& operator&=(uint128 other); + uint128& operator|=(uint128 other); + uint128& operator^=(uint128 other); + uint128& operator++(); + uint128& operator--(); + + // Uint128Low64() + // + // Returns the lower 64-bit value of a `uint128` value. + friend constexpr uint64_t Uint128Low64(uint128 v); + + // Uint128High64() + // + // Returns the higher 64-bit value of a `uint128` value. + friend constexpr uint64_t Uint128High64(uint128 v); + + // MakeUInt128() + // + // Constructs a `uint128` numeric value from two 64-bit unsigned integers. + // Note that this factory function is the only way to construct a `uint128` + // from integer values greater than 2^64. + // + // Example: + // + // absl::uint128 big = absl::MakeUint128(1, 0); + friend constexpr uint128 MakeUint128(uint64_t high, uint64_t low); + + // Uint128Max() + // + // Returns the highest value for a 128-bit unsigned integer. + friend constexpr uint128 Uint128Max(); + + private: + constexpr uint128(uint64_t high, uint64_t low); + + // TODO(strel) Update implementation to use __int128 once all users of + // uint128 are fixed to not depend on alignof(uint128) == 8. Also add + // alignas(16) to class definition to keep alignment consistent across + // platforms. +#if defined(ABSL_IS_LITTLE_ENDIAN) + uint64_t lo_; + uint64_t hi_; +#elif defined(ABSL_IS_BIG_ENDIAN) + uint64_t hi_; + uint64_t lo_; +#else // byte order +#error "Unsupported byte order: must be little-endian or big-endian." +#endif // byte order +}; + +// Prefer to use the constexpr `Uint128Max()`. +// +// TODO(absl-team) deprecate kuint128max once migration tool is released. +extern const uint128 kuint128max; + +// allow uint128 to be logged +std::ostream& operator<<(std::ostream& os, uint128 v); + +// TODO(strel) add operator>>(std::istream&, uint128) + +// TODO(absl-team): Implement signed 128-bit type + +// -------------------------------------------------------------------------- +// Implementation details follow +// -------------------------------------------------------------------------- + +constexpr uint128 MakeUint128(uint64_t high, uint64_t low) { + return uint128(high, low); +} + +constexpr uint128 Uint128Max() { + return uint128(std::numeric_limits<uint64_t>::max(), + std::numeric_limits<uint64_t>::max()); +} + +// Assignment from integer types. + +inline uint128& uint128::operator=(int v) { return *this = uint128(v); } + +inline uint128& uint128::operator=(unsigned int v) { + return *this = uint128(v); +} + +inline uint128& uint128::operator=(long v) { // NOLINT(runtime/int) + return *this = uint128(v); +} + +// NOLINTNEXTLINE(runtime/int) +inline uint128& uint128::operator=(unsigned long v) { + return *this = uint128(v); +} + +// NOLINTNEXTLINE(runtime/int) +inline uint128& uint128::operator=(long long v) { + return *this = uint128(v); +} + +// NOLINTNEXTLINE(runtime/int) +inline uint128& uint128::operator=(unsigned long long v) { + return *this = uint128(v); +} + +#ifdef ABSL_HAVE_INTRINSIC_INT128 +inline uint128& uint128::operator=(__int128 v) { + return *this = uint128(v); +} + +inline uint128& uint128::operator=(unsigned __int128 v) { + return *this = uint128(v); +} +#endif // ABSL_HAVE_INTRINSIC_INT128 + +// Arithmetic operators. + +uint128 operator<<(uint128 lhs, int amount); +uint128 operator>>(uint128 lhs, int amount); +uint128 operator+(uint128 lhs, uint128 rhs); +uint128 operator-(uint128 lhs, uint128 rhs); +uint128 operator*(uint128 lhs, uint128 rhs); +uint128 operator/(uint128 lhs, uint128 rhs); +uint128 operator%(uint128 lhs, uint128 rhs); + +inline uint128& uint128::operator<<=(int amount) { + *this = *this << amount; + return *this; +} + +inline uint128& uint128::operator>>=(int amount) { + *this = *this >> amount; + return *this; +} + +inline uint128& uint128::operator+=(uint128 other) { + *this = *this + other; + return *this; +} + +inline uint128& uint128::operator-=(uint128 other) { + *this = *this - other; + return *this; +} + +inline uint128& uint128::operator*=(uint128 other) { + *this = *this * other; + return *this; +} + +inline uint128& uint128::operator/=(uint128 other) { + *this = *this / other; + return *this; +} + +inline uint128& uint128::operator%=(uint128 other) { + *this = *this % other; + return *this; +} + +constexpr uint64_t Uint128Low64(uint128 v) { return v.lo_; } + +constexpr uint64_t Uint128High64(uint128 v) { return v.hi_; } + +// Constructors from integer types. + +#if defined(ABSL_IS_LITTLE_ENDIAN) + +constexpr uint128::uint128(uint64_t high, uint64_t low) + : lo_{low}, hi_{high} {} + +constexpr uint128::uint128(int v) + : lo_{static_cast<uint64_t>(v)}, + hi_{v < 0 ? std::numeric_limits<uint64_t>::max() : 0} {} +constexpr uint128::uint128(long v) // NOLINT(runtime/int) + : lo_{static_cast<uint64_t>(v)}, + hi_{v < 0 ? std::numeric_limits<uint64_t>::max() : 0} {} +constexpr uint128::uint128(long long v) // NOLINT(runtime/int) + : lo_{static_cast<uint64_t>(v)}, + hi_{v < 0 ? std::numeric_limits<uint64_t>::max() : 0} {} + +constexpr uint128::uint128(unsigned int v) : lo_{v}, hi_{0} {} +// NOLINTNEXTLINE(runtime/int) +constexpr uint128::uint128(unsigned long v) : lo_{v}, hi_{0} {} +// NOLINTNEXTLINE(runtime/int) +constexpr uint128::uint128(unsigned long long v) : lo_{v}, hi_{0} {} + +#ifdef ABSL_HAVE_INTRINSIC_INT128 +constexpr uint128::uint128(__int128 v) + : lo_{static_cast<uint64_t>(v & ~uint64_t{0})}, + hi_{static_cast<uint64_t>(static_cast<unsigned __int128>(v) >> 64)} {} +constexpr uint128::uint128(unsigned __int128 v) + : lo_{static_cast<uint64_t>(v & ~uint64_t{0})}, + hi_{static_cast<uint64_t>(v >> 64)} {} +#endif // ABSL_HAVE_INTRINSIC_INT128 + +#elif defined(ABSL_IS_BIG_ENDIAN) + +constexpr uint128::uint128(uint64_t high, uint64_t low) + : hi_{high}, lo_{low} {} + +constexpr uint128::uint128(int v) + : hi_{v < 0 ? std::numeric_limits<uint64_t>::max() : 0}, + lo_{static_cast<uint64_t>(v)} {} +constexpr uint128::uint128(long v) // NOLINT(runtime/int) + : hi_{v < 0 ? std::numeric_limits<uint64_t>::max() : 0}, + lo_{static_cast<uint64_t>(v)} {} +constexpr uint128::uint128(long long v) // NOLINT(runtime/int) + : hi_{v < 0 ? std::numeric_limits<uint64_t>::max() : 0}, + lo_{static_cast<uint64_t>(v)} {} + +constexpr uint128::uint128(unsigned int v) : hi_{0}, lo_{v} {} +// NOLINTNEXTLINE(runtime/int) +constexpr uint128::uint128(unsigned long v) : hi_{0}, lo_{v} {} +// NOLINTNEXTLINE(runtime/int) +constexpr uint128::uint128(unsigned long long v) : hi_{0}, lo_{v} {} + +#ifdef ABSL_HAVE_INTRINSIC_INT128 +constexpr uint128::uint128(__int128 v) + : hi_{static_cast<uint64_t>(static_cast<unsigned __int128>(v) >> 64)}, + lo_{static_cast<uint64_t>(v & ~uint64_t{0})} {} +constexpr uint128::uint128(unsigned __int128 v) + : hi_{static_cast<uint64_t>(v >> 64)}, + lo_{static_cast<uint64_t>(v & ~uint64_t{0})} {} +#endif // ABSL_HAVE_INTRINSIC_INT128 + +#else // byte order +#error "Unsupported byte order: must be little-endian or big-endian." +#endif // byte order + +// Conversion operators to integer types. + +constexpr uint128::operator bool() const { return lo_ || hi_; } + +constexpr uint128::operator char() const { return static_cast<char>(lo_); } + +constexpr uint128::operator signed char() const { + return static_cast<signed char>(lo_); +} + +constexpr uint128::operator unsigned char() const { + return static_cast<unsigned char>(lo_); +} + +constexpr uint128::operator char16_t() const { + return static_cast<char16_t>(lo_); +} + +constexpr uint128::operator char32_t() const { + return static_cast<char32_t>(lo_); +} + +constexpr uint128::operator wchar_t() const { + return static_cast<wchar_t>(lo_); +} + +// NOLINTNEXTLINE(runtime/int) +constexpr uint128::operator short() const { return static_cast<short>(lo_); } + +constexpr uint128::operator unsigned short() const { // NOLINT(runtime/int) + return static_cast<unsigned short>(lo_); // NOLINT(runtime/int) +} + +constexpr uint128::operator int() const { return static_cast<int>(lo_); } + +constexpr uint128::operator unsigned int() const { + return static_cast<unsigned int>(lo_); +} + +// NOLINTNEXTLINE(runtime/int) +constexpr uint128::operator long() const { return static_cast<long>(lo_); } + +constexpr uint128::operator unsigned long() const { // NOLINT(runtime/int) + return static_cast<unsigned long>(lo_); // NOLINT(runtime/int) +} + +constexpr uint128::operator long long() const { // NOLINT(runtime/int) + return static_cast<long long>(lo_); // NOLINT(runtime/int) +} + +constexpr uint128::operator unsigned long long() const { // NOLINT(runtime/int) + return static_cast<unsigned long long>(lo_); // NOLINT(runtime/int) +} + +#ifdef ABSL_HAVE_INTRINSIC_INT128 +constexpr uint128::operator __int128() const { + return (static_cast<__int128>(hi_) << 64) + lo_; +} + +constexpr uint128::operator unsigned __int128() const { + return (static_cast<unsigned __int128>(hi_) << 64) + lo_; +} +#endif // ABSL_HAVE_INTRINSIC_INT128 + +// Conversion operators to floating point types. + +inline uint128::operator float() const { + return static_cast<float>(lo_) + std::ldexp(static_cast<float>(hi_), 64); +} + +inline uint128::operator double() const { + return static_cast<double>(lo_) + std::ldexp(static_cast<double>(hi_), 64); +} + +inline uint128::operator long double() const { + return static_cast<long double>(lo_) + + std::ldexp(static_cast<long double>(hi_), 64); +} + +// Comparison operators. + +inline bool operator==(uint128 lhs, uint128 rhs) { + return (Uint128Low64(lhs) == Uint128Low64(rhs) && + Uint128High64(lhs) == Uint128High64(rhs)); +} + +inline bool operator!=(uint128 lhs, uint128 rhs) { + return !(lhs == rhs); +} + +inline bool operator<(uint128 lhs, uint128 rhs) { + return (Uint128High64(lhs) == Uint128High64(rhs)) + ? (Uint128Low64(lhs) < Uint128Low64(rhs)) + : (Uint128High64(lhs) < Uint128High64(rhs)); +} + +inline bool operator>(uint128 lhs, uint128 rhs) { + return (Uint128High64(lhs) == Uint128High64(rhs)) + ? (Uint128Low64(lhs) > Uint128Low64(rhs)) + : (Uint128High64(lhs) > Uint128High64(rhs)); +} + +inline bool operator<=(uint128 lhs, uint128 rhs) { + return (Uint128High64(lhs) == Uint128High64(rhs)) + ? (Uint128Low64(lhs) <= Uint128Low64(rhs)) + : (Uint128High64(lhs) <= Uint128High64(rhs)); +} + +inline bool operator>=(uint128 lhs, uint128 rhs) { + return (Uint128High64(lhs) == Uint128High64(rhs)) + ? (Uint128Low64(lhs) >= Uint128Low64(rhs)) + : (Uint128High64(lhs) >= Uint128High64(rhs)); +} + +// Unary operators. + +inline uint128 operator-(uint128 val) { + uint64_t hi = ~Uint128High64(val); + uint64_t lo = ~Uint128Low64(val) + 1; + if (lo == 0) ++hi; // carry + return MakeUint128(hi, lo); +} + +inline bool operator!(uint128 val) { + return !Uint128High64(val) && !Uint128Low64(val); +} + +// Logical operators. + +inline uint128 operator~(uint128 val) { + return MakeUint128(~Uint128High64(val), ~Uint128Low64(val)); +} + +inline uint128 operator|(uint128 lhs, uint128 rhs) { + return MakeUint128(Uint128High64(lhs) | Uint128High64(rhs), + Uint128Low64(lhs) | Uint128Low64(rhs)); +} + +inline uint128 operator&(uint128 lhs, uint128 rhs) { + return MakeUint128(Uint128High64(lhs) & Uint128High64(rhs), + Uint128Low64(lhs) & Uint128Low64(rhs)); +} + +inline uint128 operator^(uint128 lhs, uint128 rhs) { + return MakeUint128(Uint128High64(lhs) ^ Uint128High64(rhs), + Uint128Low64(lhs) ^ Uint128Low64(rhs)); +} + +inline uint128& uint128::operator|=(uint128 other) { + hi_ |= other.hi_; + lo_ |= other.lo_; + return *this; +} + +inline uint128& uint128::operator&=(uint128 other) { + hi_ &= other.hi_; + lo_ &= other.lo_; + return *this; +} + +inline uint128& uint128::operator^=(uint128 other) { + hi_ ^= other.hi_; + lo_ ^= other.lo_; + return *this; +} + +// Arithmetic operators. + +inline uint128 operator<<(uint128 lhs, int amount) { + // uint64_t shifts of >= 64 are undefined, so we will need some + // special-casing. + if (amount < 64) { + if (amount != 0) { + return MakeUint128( + (Uint128High64(lhs) << amount) | (Uint128Low64(lhs) >> (64 - amount)), + Uint128Low64(lhs) << amount); + } + return lhs; + } + return MakeUint128(Uint128Low64(lhs) << (amount - 64), 0); +} + +inline uint128 operator>>(uint128 lhs, int amount) { + // uint64_t shifts of >= 64 are undefined, so we will need some + // special-casing. + if (amount < 64) { + if (amount != 0) { + return MakeUint128(Uint128High64(lhs) >> amount, + (Uint128Low64(lhs) >> amount) | + (Uint128High64(lhs) << (64 - amount))); + } + return lhs; + } + return MakeUint128(0, Uint128High64(lhs) >> (amount - 64)); +} + +inline uint128 operator+(uint128 lhs, uint128 rhs) { + uint128 result = MakeUint128(Uint128High64(lhs) + Uint128High64(rhs), + Uint128Low64(lhs) + Uint128Low64(rhs)); + if (Uint128Low64(result) < Uint128Low64(lhs)) { // check for carry + return MakeUint128(Uint128High64(result) + 1, Uint128Low64(result)); + } + return result; +} + +inline uint128 operator-(uint128 lhs, uint128 rhs) { + uint128 result = MakeUint128(Uint128High64(lhs) - Uint128High64(rhs), + Uint128Low64(lhs) - Uint128Low64(rhs)); + if (Uint128Low64(lhs) < Uint128Low64(rhs)) { // check for carry + return MakeUint128(Uint128High64(result) - 1, Uint128Low64(result)); + } + return result; +} + +inline uint128 operator*(uint128 lhs, uint128 rhs) { +#if defined(ABSL_HAVE_INTRINSIC_INT128) + // TODO(strel) Remove once alignment issues are resolved and unsigned __int128 + // can be used for uint128 storage. + return static_cast<unsigned __int128>(lhs) * + static_cast<unsigned __int128>(rhs); +#else // ABSL_HAVE_INTRINSIC128 + uint64_t a32 = Uint128Low64(lhs) >> 32; + uint64_t a00 = Uint128Low64(lhs) & 0xffffffff; + uint64_t b32 = Uint128Low64(rhs) >> 32; + uint64_t b00 = Uint128Low64(rhs) & 0xffffffff; + uint128 result = + MakeUint128(Uint128High64(lhs) * Uint128Low64(rhs) + + Uint128Low64(lhs) * Uint128High64(rhs) + a32 * b32, + a00 * b00); + result += uint128(a32 * b00) << 32; + result += uint128(a00 * b32) << 32; + return result; +#endif // ABSL_HAVE_INTRINSIC128 +} + +// Increment/decrement operators. + +inline uint128 uint128::operator++(int) { + uint128 tmp(*this); + *this += 1; + return tmp; +} + +inline uint128 uint128::operator--(int) { + uint128 tmp(*this); + *this -= 1; + return tmp; +} + +inline uint128& uint128::operator++() { + *this += 1; + return *this; +} + +inline uint128& uint128::operator--() { + *this -= 1; + return *this; +} + +#if defined(ABSL_HAVE_INTRINSIC_INT128) +#include "absl/numeric/int128_have_intrinsic.inc" +#else // ABSL_HAVE_INTRINSIC_INT128 +#include "absl/numeric/int128_no_intrinsic.inc" +#endif // ABSL_HAVE_INTRINSIC_INT128 + +} // namespace absl + +#endif // ABSL_NUMERIC_INT128_H_ http://git-wip-us.apache.org/repos/asf/marmotta/blob/0eb556da/libraries/ostrich/backend/3rdparty/abseil/absl/numeric/int128_have_intrinsic.inc ---------------------------------------------------------------------- diff --git a/libraries/ostrich/backend/3rdparty/abseil/absl/numeric/int128_have_intrinsic.inc b/libraries/ostrich/backend/3rdparty/abseil/absl/numeric/int128_have_intrinsic.inc new file mode 100644 index 0000000..ee2a093 --- /dev/null +++ b/libraries/ostrich/backend/3rdparty/abseil/absl/numeric/int128_have_intrinsic.inc @@ -0,0 +1,18 @@ +// +// Copyright 2017 The Abseil Authors. +// +// 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. + +// This file contains :int128 implementation details that depend on internal +// representation when ABSL_HAVE_INTRINSIC_INT128 is defined. This file is +// included by int128.h. http://git-wip-us.apache.org/repos/asf/marmotta/blob/0eb556da/libraries/ostrich/backend/3rdparty/abseil/absl/numeric/int128_no_intrinsic.inc ---------------------------------------------------------------------- diff --git a/libraries/ostrich/backend/3rdparty/abseil/absl/numeric/int128_no_intrinsic.inc b/libraries/ostrich/backend/3rdparty/abseil/absl/numeric/int128_no_intrinsic.inc new file mode 100644 index 0000000..0d0b3cf --- /dev/null +++ b/libraries/ostrich/backend/3rdparty/abseil/absl/numeric/int128_no_intrinsic.inc @@ -0,0 +1,18 @@ +// +// Copyright 2017 The Abseil Authors. +// +// 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. + +// This file contains :int128 implementation details that depend on internal +// representation when ABSL_HAVE_INTRINSIC_INT128 is *not* defined. This file +// is included by int128.h.
