// bslmf_integersequence.h -*-C++-*- #ifndef INCLUDED_BSLMF_INTEGERSEQUENCE #define INCLUDED_BSLMF_INTEGERSEQUENCE #include <bsls_ident.h> BSLS_IDENT("$Id: $") //@PURPOSE: Provide a template parameter pack of integers. // //@CLASSES: // bslmf::IntegerSequence: a compile-time sequence of integers // //@DESCRIPTION: This component defines a class template, // 'bslmf::IntegerSequence', which can be used in parameter pack expansions. // // 'bslmf::IntegerSequence' meets the requirements of the 'integer_sequence' // template introduced in the C++14 standard [intseq.intseq] and can be used in // a client's code if the compiler supports the C++11 standard. // // Note, that this component has no (emulated) support for pre-standard C++11 // compilers, as its only purpose is to be used in deduction with template // parameter packs. There is no language support to emulate in earlier // compilers. // ///Usage ///----- // In this section we show intended use of this component. // ///Example 1: Pass C-array as a parameter to a function with variadic template ///- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Suppose we want to initialize a C-Array of known size 't_N' with data read // from a data source using a library class that provides a variadic template // interface that loads a data of variable length into the supplied parameter // pack. // // First, define a class template 'DataReader', //.. // template <std::size_t t_N> // class DataReader { // public: //.. // Then, implement a method that loads the specified parameter pack 'args' with // data read from a data source. //.. // template <class ...t_T> // void read(t_T*... args) const // { // static_assert(sizeof...(args) == t_N, ""); // read_impl(args...); // } //.. // Next, for the test purpose provide simple implementation of the recursive // variadic 'read_impl' function that streams the index of the C-Array's // element to 'stdout'. //.. // private: // template <class t_U, class ...t_T> // void read_impl(t_U*, t_T*... args) const // { // printf("read element #%i\n", // static_cast<int>(t_N - 1 - sizeof...(args))); // read_impl(args...); // } //.. // Then, implement the recursion break condition. //.. // void read_impl() const // { // } // }; //.. // Next, define a helper function template 'readData' that expands the // parameter pack of indices 't_I' and invokes the variadic template 'read' // method of the specified 'reader' object. //.. // namespace { // template<class t_R, class t_T, std::size_t... t_I> // void readData(const t_R& reader, // t_T *data, // bslmf::IntegerSequence<std::size_t, t_I...>) // { // reader.read(&data[t_I]...); // // In pseudocode, this is equivalent to: // // reader.read(&data[0], // // &data[1], // // &data[2], // // ... // // &data[t_N-1]); // } // } //.. // Finally, define a 'data' C-Array and 'reader' variables and pass them to the // 'readData' function as parameters. //.. // constexpr int k_SIZE = 5; // DataReader<k_SIZE> reader; // int data[k_SIZE] = {0}; // // readData(reader, // data, // bslmf::IntegerSequence<size_t, 0, 1, 2, 3, 4>()); //.. // Note that using a direct call to the 'bslmf::IntegerSequence' constructor // looks a bit clumsy here. The better approach is to use alias template // 'bslmf::MakeIntegerSequence', that creates a collection of increasing // integer values, having the specified t_N-value length. The usage example in // that component shows this method more clearly. But we can not afford its // presence here to avoid a cycle/levelization violation. // // The streaming operator produces output in the following format on 'stdout': //.. // read element #0 // read element #1 // read element #2 // read element #3 // read element #4 //.. #include <bslscm_version.h> #include <bslmf_integralconstant.h> #include <bsls_libraryfeatures.h> #include <cstddef> // 'std::size_t' #ifdef BSLS_LIBRARYFEATURES_HAS_CPP14_INTEGER_SEQUENCE namespace BloombergLP { namespace bslmf { // ====================== // struct IntegerSequence // ====================== template <class t_T, t_T ...t_INTS> struct IntegerSequence { // This class template represents a compile-time sequence of integers. // When passed as an argument to a function template, the specified // parameter pack 't_INTS' can be deduced and used a in pack expansion. // TYPES typedef t_T value_type; // 'value_type' is an alias to the template parameter 't_T' that // represents an integer type to use for the elements of the sequence. // CLASS METHODS static constexpr std::size_t size() noexcept; // Return the number of elements in 't_INTS'. }; } // close package namespace // ============================================================================ // INLINE FUNCTION DEFINITIONS // ============================================================================ // ---------------------- // struct IntegerSequence // ---------------------- template <class t_T, t_T... t_INTS> inline constexpr std::size_t bslmf::IntegerSequence<t_T, t_INTS...>::size() noexcept { return sizeof...(t_INTS); } } // close enterprise namespace #endif // BSLS_LIBRARYFEATURES_HAS_CPP14_INTEGER_SEQUENCE #endif // INCLUDED_BSLMF_INTEGERSEQUENCE // ---------------------------------------------------------------------------- // Copyright 2018 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 ----------------------------------