/* * Copyright Amazon.com, Inc. or its affiliates. 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. * A copy of the License is located at * * http://aws.amazon.com/apache2.0/ * * or in the "license" file accompanying this file. This file 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 ManufactoryUtilsTest.cpp /** * Test of acsdkManufactory's compile time utilities. */ #include #include #include #include #include "acsdkManufactory/Import.h" #include "acsdkManufactory/OptionalImport.h" #include "acsdkManufactory/internal/Utils.h" namespace alexaClientSDK { namespace acsdkManufactory { namespace internal { /** * Template used to create distinct classes with which to test compile time utilities. * * @tparam x An integer used to distinguish between instantiations of this template. */ template class Foo { public: }; /** * Function used to invoke compile time utilities. */ TEST(ManufactoryUtilsTest, manufactoryUtilsFunctions) { // Test ContainsType static_assert(!ContainsType, Foo<1>>::value, "test"); static_assert(ContainsType>, Foo<1>>::value, "test"); static_assert(!ContainsType>, Foo<1>>::value, "test"); static_assert(ContainsType, Foo<2>>, Foo<1>>::value, "test"); static_assert(!ContainsType, Foo<2>>, Foo<3>>::value, "test"); static_assert(ContainsType, Foo<1>>, Foo<1>>::value, "test"); static_assert(!ContainsType, Foo<2>>, Foo<1>>::value, "test"); static_assert(ContainsType, Foo<2>, Foo<3>>, Foo<3>>::value, "test"); static_assert(!ContainsType, Foo<2>, Foo<3>>, Foo<4>>::value, "test"); // Test ContainsTypes static_assert(!ContainsTypes, Foo<1>>::value, "test"); static_assert(ContainsTypes>, Foo<1>>::value, "test"); static_assert(!ContainsTypes>, Foo<2>>::value, "test"); static_assert(!ContainsTypes>, Foo<1>, Foo<2>>::value, "test"); static_assert(ContainsTypes, Foo<2>>, Foo<1>>::value, "test"); static_assert(ContainsTypes, Foo<2>>, Foo<1>, Foo<1>>::value, "test"); static_assert(ContainsTypes, Foo<2>>, Foo<2>, Foo<2>>::value, "test"); static_assert(ContainsTypes, Foo<2>>, Foo<1>, Foo<2>>::value, "test"); static_assert(ContainsTypes, Foo<1>>, Foo<1>>::value, "test"); static_assert(!ContainsTypes, Foo<1>>, Foo<2>>::value, "test"); static_assert(ContainsTypes, Foo<2>, Foo<3>>, Foo<1>>::value, "test"); static_assert(!ContainsTypes, Foo<2>, Foo<3>>, Foo<4>>::value, "test"); // Test ContainsTupleTypes static_assert(ContainsTupleTypes, std::tuple<>>::value, "test"); static_assert(!ContainsTupleTypes, std::tuple>>::value, "test"); static_assert(ContainsTupleTypes, Foo<1>>, std::tuple<>>::value, "test"); static_assert(ContainsTupleTypes, Foo<1>>, std::tuple>>::value, "test"); static_assert(!ContainsTupleTypes, Foo<1>>, std::tuple>>::value, "test"); static_assert(ContainsTupleTypes, Foo<2>>, std::tuple<>>::value, "test"); static_assert(ContainsTupleTypes, Foo<2>>, std::tuple>>::value, "test"); static_assert(ContainsTupleTypes, Foo<2>>, std::tuple>>::value, "test"); static_assert(ContainsTupleTypes, Foo<2>>, std::tuple, Foo<2>>>::value, "test"); static_assert(!ContainsTupleTypes, Foo<2>>, std::tuple, Foo<3>>>::value, "test"); static_assert(!ContainsTupleTypes, Foo<2>>, std::tuple, Foo<2>>>::value, "test"); // Test HasRequiredImport static_assert(!HasRequiredImport<>::value, "test"); static_assert(!HasRequiredImport>::value, "test"); static_assert(HasRequiredImport>>::value, "test"); static_assert(!HasRequiredImport, Foo<2>>::value, "test"); static_assert(HasRequiredImport>, Foo<2>>::value, "test"); static_assert(HasRequiredImport>, Import>>::value, "test"); static_assert(HasRequiredImport, Import>>::value, "test"); static_assert(!HasRequiredImport, Foo<2>, Foo<3>>::value, "test"); static_assert(HasRequiredImport>, Foo<2>, Foo<3>>::value, "test"); static_assert(HasRequiredImport>, Import, Foo<3>>>::value, "test"); static_assert(HasRequiredImport, Import>, Foo<3>>::value, "test"); static_assert(!HasRequiredImport, Foo<1>>::value, "test"); static_assert(HasRequiredImport>, Import>>::value, "test"); static_assert(!HasRequiredImport>, Foo<1>>::value, "test"); static_assert(!HasRequiredImport, Foo<1>>>::value, "test"); static_assert(HasRequiredImport>, Import>>::value, "test"); // Test IsRequiredImport static_assert(!IsRequiredImport>::value, "test"); static_assert(IsRequiredImport>>::value, "test"); static_assert(!IsRequiredImport>>::value, "test"); // Test DedupTypes DedupTypes<>::type x1 = {}; DedupTypes>::type x2((Foo<1>())); DedupTypes, Foo<1>>::type x3((Foo<1>())); DedupTypes, Foo<2>>::type x4((Foo<1>()), (Foo<2>())); DedupTypes, Foo<2>, Foo<2>>::type x5((Foo<1>()), (Foo<2>())); DedupTypes, Foo<2>, Foo<1>, Foo<2>>::type x6((Foo<1>()), (Foo<2>())); DedupTypes, Foo<2>, Foo<2>, Foo<1>>::type x7((Foo<1>()), (Foo<2>())); DedupTypes, Foo<2>, Foo<3>, Foo<2>, Foo<1>>::type x8((Foo<1>()), (Foo<2>()), (Foo<3>())); DedupTypes, Foo<2>, Foo<3>, Foo<2>, Foo<3>, Foo<1>>::type x9((Foo<1>()), (Foo<2>()), (Foo<3>())); DedupTypes, Foo<2>, Foo<3>, Foo<2>, Foo<2>, Foo<2>>::type x10((Foo<1>()), (Foo<2>()), (Foo<3>())); // Avoid annoying "unused variable" warnings. std::cout << &x1 << &x2 << &x3 << &x4 << &x5 << &x6 << &x7 << &x8 << &x9 << &x10; // Test RemoveTypes RemoveTypes, std::tuple<>>::type x11 = {}; RemoveTypes>, std::tuple<>>::type x12((Foo<1>())); RemoveTypes>, std::tuple>>::type x13 = {}; RemoveTypes, Foo<2>>, std::tuple<>>::type x14((Foo<1>()), (Foo<2>())); RemoveTypes, Foo<2>>, std::tuple>>::type x15((Foo<2>())); RemoveTypes, Foo<2>>, std::tuple>>::type x16((Foo<1>())); RemoveTypes, Foo<1>>, std::tuple>>::type x17 = {}; RemoveTypes, Foo<1>>, std::tuple, Foo<1>>>::type x18 = {}; RemoveTypes, Foo<1>>, std::tuple>>::type x19((Foo<1>()), (Foo<1>())); RemoveTypes, Foo<2>, Foo<3>>, std::tuple, Foo<3>, Foo<2>>>::type x20((Foo<1>())); // Avoid annoying "unused variable" warnings. std::cout << &x11 << &x12 << &x13 << &x14 << &x15 << &x16 << &x17 << &x18 << &x19 << &x20; // Test GetImportsAndExports GetImportsAndExports<>::type::exports x21 = {}; GetImportsAndExports<>::type::required x22 = {}; GetImportsAndExports>::type::exports x23((Foo<1>())); GetImportsAndExports>::type::required x24 = {}; GetImportsAndExports, Foo<1>>::type::exports x25((Foo<1>())); GetImportsAndExports, Foo<1>>::type::required x26 = {}; GetImportsAndExports, Foo<2>>::type::exports x27((Foo<1>()), (Foo<2>())); GetImportsAndExports, Foo<2>>::type::required x28 = {}; GetImportsAndExports, Foo<2>, Foo<3>>::type::exports x29((Foo<1>()), (Foo<2>()), (Foo<3>())); GetImportsAndExports, Foo<2>, Foo<3>>::type::required x30 = {}; GetImportsAndExports>, Foo<2>, Foo<3>>::type::exports x31((Foo<2>()), (Foo<3>())); GetImportsAndExports>, Foo<2>, Foo<3>>::type::required x32((Foo<1>())); GetImportsAndExports>, Import>, Foo<3>>::type::exports x33((Foo<3>())); GetImportsAndExports>, Import>, Foo<3>>::type::required x34((Foo<1>()), (Foo<2>())); GetImportsAndExports>, Import>, Import>>::type::exports x35 = {}; GetImportsAndExports>, Import>, Import>>::type::required x36( (Foo<1>()), (Foo<2>()), (Foo<3>())); GetImportsAndExports, Import>, Import>>::type::exports x37((Foo<1>())); GetImportsAndExports, Import>, Import>>::type::required x38((Foo<2>()), (Foo<3>())); // Avoid annoying "unused variable" warnings. std::cout << &x21 << &x22 << &x23 << &x24 << &x25 << &x26 << &x27 << &x28 << &x29 << &x30; std::cout << &x31 << &x32 << &x33 << &x34 << &x35 << &x36 << &x37 << &x38; // Test Required x Optional Import / Exports static_assert(std::tuple_size::type::optional>() == 0, "test"); static_assert(std::tuple_size>::type::optional>() == 0, "test"); static_assert(std::tuple_size, Foo<1>>::type::optional>() == 0, "test"); static_assert(std::tuple_size, Foo<2>>::type::optional>() == 0, "test"); static_assert(std::tuple_size, Foo<2>, Foo<3>>::type::optional>() == 0, "test"); static_assert(std::tuple_size>, Foo<2>, Foo<3>>::type::optional>() == 0, "test"); // Test static_assert(std::tuple_size>>::type::optional, Foo<1>>::value, "test"); static_assert(!ContainsType>>::type::required, Foo<1>>::value, "test"); // With export static_assert( !ContainsType, OptionalImport>>::type::optional, Foo<1>>::value, "test"); static_assert( !ContainsType, Import>, OptionalImport>>::type::optional, Foo<1>>:: value, "test"); // Different combinations of Import and OptionalImport. static_assert( !ContainsType>, OptionalImport>>::type::optional, Foo<1>>::value, "test"); static_assert( ContainsType>, OptionalImport>>::type::required, Foo<1>>::value, "test"); static_assert( !ContainsType>, OptionalImport>>::type::optional, Foo<1>>::value, "test"); static_assert( ContainsType>, OptionalImport>>::type::optional, Foo<2>>::value, "test"); static_assert( ContainsType>, OptionalImport>>::type::required, Foo<1>>::value, "test"); static_assert( !ContainsType>, OptionalImport>>::type::required, Foo<2>>::value, "test"); // Test make optional import. static_assert( ContainsType>, MakeOptional>>::type::optional, Foo<1>>::value, "test"); static_assert( !ContainsType>, MakeOptional>>::type::required, Foo<1>>::value, "test"); // Test that large numbers of template parameters don't trigger degenerate compiler behavior. GetImportsAndExports< Import>, Foo<2>, std::shared_ptr>, std::shared_ptr>, Import>, Import>, Import>, Foo<8>, Import>>, Foo<10>, Import>, Foo<12>, Import>, Import>, Foo<15>, Foo<16>, Foo<17>, Import>, Import>, Import>, Foo<21>, Import>, Foo<23>, Import>, Import>, Import>>, Foo<27>, Foo<28>, Import>>, OptionalImport>>, OptionalImport>, Import>, Import>, Foo<34>, std::shared_ptr>, MakeOptional>>, Import>>, Foo<37>, std::shared_ptr>, std::shared_ptr>, std::shared_ptr>, Foo<41>, Foo<42>, Foo<43>, Foo<44>, Foo<45>, Foo<46>, Foo<47>, Foo<48>, Foo<49>, Foo<50>, Foo<51>, Foo<52>, Foo<53>, Foo<54>, Foo<55>, Foo<56>, Foo<57>, Foo<58>, Foo<59>, Foo<60>, Foo<61>, Foo<62>, Foo<63>, Foo<64>, Foo<65>, Foo<66>, Foo<67>, Foo<68>, Foo<69>, Foo<70>, Foo<71>, Foo<72>, Foo<73>, Foo<74>, Foo<75>, Foo<76>, Foo<77>, Foo<78>, Foo<79>, Foo<80>, Foo<81>, Foo<82>, Foo<83>, Foo<84>, Foo<85>, Foo<86>, Foo<87>, Foo<88>, Foo<89>, Foo<90>, Foo<91>, Foo<92>, Foo<93>, Foo<94>, Foo<85>, Foo<96>, Foo<97>, Foo<98>, Foo<99>, Foo<100>>::type::exports x39; // Avoid annoying "unused variable" warnings. std::cerr << &x39; }; } // namespace internal } // namespace acsdkManufactory } // namespace alexaClientSDK