/* * static-string.h * Copyright (C) 2010-2018 Belledonne Communications SARL * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef _L_STATIC_STRING_H_ #define _L_STATIC_STRING_H_ #include "linphone/utils/general.h" // ============================================================================= // Compile time strings. Useful to build const char * at compilation. // ============================================================================= LINPHONE_BEGIN_NAMESPACE template struct IndexSequence { using Type = IndexSequence; }; namespace Private { template struct ConcatIndexSequenceImpl; template struct ConcatIndexSequenceImpl, IndexSequence> : IndexSequence {}; template struct MakeIndexSequenceImpl : ConcatIndexSequenceImpl< typename MakeIndexSequenceImpl::Type, typename MakeIndexSequenceImpl::Type > {}; template<> struct MakeIndexSequenceImpl<0> : IndexSequence<> {}; template<> struct MakeIndexSequenceImpl<1> : IndexSequence<0> {}; } template using MakeIndexSequence = typename Private::MakeIndexSequenceImpl::Type; // ============================================================================= // See: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4121.pdf template using RawStaticString = const char [N]; namespace Private { template> struct StaticString; template struct StaticString> { constexpr StaticString (const RawStaticString &inRaw) : raw{ (inRaw[Index])... } {} constexpr char operator[] (std::size_t i) const { return raw[i]; } constexpr operator const char * () const { return raw; } RawStaticString raw; }; template class StaticStringConcatHelper { public: template constexpr StaticStringConcatHelper( const Private::StaticString &s1, const Private::StaticString &s2 ) : StaticStringConcatHelper(s1, s2, MakeIndexSequence{}, MakeIndexSequence{}) {} RawStaticString raw; private: template constexpr StaticStringConcatHelper( const Private::StaticString &s1, const Private::StaticString &s2, IndexSequence, IndexSequence ) : raw{ s1[Index1]..., s2[Index2]... } {} }; template class StaticIntStringHelper { public: constexpr StaticIntStringHelper () : StaticIntStringHelper(MakeIndexSequence= 0 ? N - 1 : N - 2>{}) {} RawStaticString raw; private: template= 0, int>::type* = nullptr> constexpr StaticIntStringHelper (const IndexSequence &) : raw{ char('0' + Value / pow10(N - Index - 2) % 10 )..., '\0' } {} template::type* = nullptr> constexpr StaticIntStringHelper (const IndexSequence &) : raw{ '-', char('0' + abs(Value) / pow10(N - Index - 3) % 10 )..., '\0' } {} }; }; // ----------------------------------------------------------------------------- template constexpr Private::StaticString StaticString (const RawStaticString &raw) { return Private::StaticString(raw); } template constexpr Private::StaticString operator+ ( const Private::StaticString &s1, const Private::StaticString &s2 ) { return StaticString(Private::StaticStringConcatHelper(s1, s2).raw); } template constexpr Private::StaticString operator+ ( const Private::StaticString &s1, const RawStaticString &s2 ) { return StaticString(Private::StaticStringConcatHelper(s1, StaticString(s2)).raw); } template constexpr Private::StaticString operator+ ( const RawStaticString &s1, const Private::StaticString &s2 ) { return StaticString(Private::StaticStringConcatHelper(StaticString(s1), s2).raw); } // ----------------------------------------------------------------------------- template constexpr Private::StaticString StaticIntString () { return StaticString(Private::StaticIntStringHelper().raw); } // ----------------------------------------------------------------------------- LINPHONE_END_NAMESPACE #endif // ifndef _L_STATIC_STRING_H_