// bslmf_nthparameter.h -*-C++-*- #ifndef INCLUDED_BSLMF_NTHPARAMETER #define INCLUDED_BSLMF_NTHPARAMETER #include <bsls_ident.h> BSLS_IDENT("$Id: $") //@PURPOSE: Metafunction to return the Nth type parameter in a parameter pack // //@CLASSES: bslmf::NthParameter<t_N, PARAM_0, t_PARAMS...> // //@SEE_ALSO: // //@DESCRIPTION: This component contains a metafunction that treats a // parameter pack of types as compile-time array of types, returning the Nth // type (counting from zero). It is useful for implementing types like // 'tuple' that need access to a specific element of a parameter pack. // ///Usage ///----- // We wish to implement a 'tuple'-like class that holds a heterogeneous // collection of elements, each of which might have a different type. The // metafunction, 'my_tuple_element<I, my_tuple<ELEMS...>>::Type' would be type // of the 'I'th element in the tuple (where 'I' is zero-based). // // First, we define our 'my_tuple' class template. The body of the class is // unimportant for this usage examples: //.. // template <class... ELEMS> // class my_tuple { // // ... // }; //.. // Then, we use 'bslmf::NthParameter' to implement 'my_tuple_element': //.. // #include <bslmf_nthparameter.h> // // template <std::size_t I, class TUPLE> // struct my_tuple_element; // Not defined // // template <std::size_t I, class... ELEMS> // struct my_tuple_element<I, my_tuple<ELEMS...> > { // typedef typename bslmf::NthParameter<I, ELEMS...>::Type Type; // }; //.. // Finally, we test this implementation using 'bsl::is_same': //.. // #include <bslmf_issame.h> // // int main() // { // typedef my_tuple<int, short, char*> ttype; // // assert((bsl::is_same<int, my_tuple_element<0, ttype>::Type>::value)); // assert((bsl::is_same<short, my_tuple_element<1, ttype>::Type>::value)); // assert((bsl::is_same<char *, my_tuple_element<2, ttype>::Type>::value)); // // assert(! (bsl::is_same<short, my_tuple_element<0, ttype>::Type>::value)); // } //.. #include <bsls_compilerfeatures.h> #include <bslmf_assert.h> #include <bsls_compilerfeatures.h> #include <cstddef> #if BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES // Include version that can be compiled with C++03 // Generated on Fri Dec 16 11:47:20 2022 // Command line: sim_cpp11_features.pl bslmf_nthparameter.h # define COMPILING_BSLMF_NTHPARAMETER_H # include <bslmf_nthparameter_cpp03.h> # undef COMPILING_BSLMF_NTHPARAMETER_H #else namespace BloombergLP { namespace bslmf { // =========================== // class template NthParameter // =========================== struct NthParameter_Sentinel; // Declared but not defined #if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES // $var-args=15 template <std::size_t t_N, class t_FIRST_PARAM = NthParameter_Sentinel, class... t_PARAMS> struct NthParameter { // Metafunction to compute the specified 't_N'th element of the specified // 't_PARAMS' template parameter pack. The 'Type' nested typedef will // match the 't_N'th element of 't_PARAMS', where 't_N' is zero-based (so // that an 't_N' of zero corresponds to the first parameter. typedef typename NthParameter<t_N - 1, t_PARAMS...>::Type Type; // The type of the Nth parameter, computed by recursively stripping off // the first parameter until t_N == 0. }; // ============================================================================ // IMPLEMENTATION // ============================================================================ template <class t_FIRST_PARAM, class... t_PARAMS> struct NthParameter<0, t_FIRST_PARAM, t_PARAMS...> { // Specialization of 'NthParameter' for when 't_N' is zero. typedef t_FIRST_PARAM Type; // The type of the 0th parameter. }; #endif template <> struct NthParameter<0, NthParameter_Sentinel> { // Specialization of 'NthParameter' for when 't_N' exceeds the actual // number of parameters. #ifdef BSLS_COMPILERFEATURES_SUPPORT_VARIADIC_TEMPLATES // No 'Type' member is defined. #else // There are no dependent parameters because this is a full specialization. // When used in another simulated variadic template, the compiler may // attempt to evaluate the 'Type' member even when that client is not // actually instantiated. To avoid a spurious compilation error, we must // therefore make sure that 'Type' is defined, even if it is defined as an // incomplete class. typedef NthParameter_Sentinel Type; #endif }; } // close package namespace } // close enterprise namespace #endif // End C++11 code #endif // ! defined(INCLUDED_BSLMF_NTHPARAMETER) // ---------------------------------------------------------------------------- // Copyright 2019 Bloomberg Finance L.P. // // 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. // ----------------------------- END-OF-FILE ----------------------------------