mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-01-30 01:39:20 +00:00
Many things:
- Provide a StaticString object to build const char* at compile time - Use StaticString in MainDb to transforms enum in const char* automatically (events filters) - In future: Abuse of this component in MainDb to build queries easily between Mysql/Sqlite3
This commit is contained in:
parent
07b33a419e
commit
e0b2b41290
3 changed files with 260 additions and 18 deletions
|
|
@ -114,6 +114,8 @@ std::unique_ptr<T> makeUnique(Args && ...args) {
|
|||
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
|
||||
}
|
||||
|
||||
#define L_AUTO_RETURN(VALUE) -> decltype(VALUE) { return VALUE; }
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Class tools.
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
@ -259,17 +261,13 @@ namespace Private {
|
|||
template<typename... Args>
|
||||
struct ResolveMemberFunctionOverload {
|
||||
template<typename Ret, typename Obj>
|
||||
constexpr auto operator() (Ret (Obj::*func)(Args...)) const -> decltype(func) {
|
||||
return func;
|
||||
}
|
||||
constexpr auto operator() (Ret (Obj::*func)(Args...)) const L_AUTO_RETURN(func);
|
||||
};
|
||||
|
||||
template<typename... Args>
|
||||
struct ResolveConstMemberFunctionOverload {
|
||||
template<typename Ret, typename Obj>
|
||||
constexpr auto operator() (Ret (Obj::*func)(Args...) const) const -> decltype(func) {
|
||||
return func;
|
||||
}
|
||||
constexpr auto operator() (Ret (Obj::*func)(Args...) const) L_AUTO_RETURN(func);
|
||||
};
|
||||
|
||||
template<typename... Args>
|
||||
|
|
@ -278,9 +276,7 @@ namespace Private {
|
|||
using ResolveConstMemberFunctionOverload<Args...>::operator();
|
||||
|
||||
template<typename Ret>
|
||||
constexpr auto operator() (Ret (*func)(Args...)) const -> decltype(func) {
|
||||
return func;
|
||||
}
|
||||
constexpr auto operator() (Ret (*func)(Args...)) const L_AUTO_RETURN(func);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -288,6 +284,40 @@ namespace Private {
|
|||
template<typename... Args>
|
||||
using resolveOverload = Private::ResolveOverload<Args...>;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Math.
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// Get the length of one integer.
|
||||
constexpr int getIntLength (int n) {
|
||||
return n < 0 ? 1 + getIntLength(-n) : (n < 10 ? 1 : 1 + getIntLength(n / 10));
|
||||
}
|
||||
|
||||
namespace Private {
|
||||
constexpr int pow10Impl (int n, int acc) {
|
||||
return n == 0 ? acc : pow10Impl(n - 1, acc * 10);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
constexpr T abs (const T &value) {
|
||||
return value < 0 ? -value : value;
|
||||
}
|
||||
|
||||
constexpr int pow10 (int n) {
|
||||
return (n < 0 ? -1 : +1) * Private::pow10Impl(abs(n), 1);
|
||||
}
|
||||
|
||||
// Returns the sum of n elements.
|
||||
constexpr int sums () {
|
||||
return 0;
|
||||
}
|
||||
|
||||
template<typename T, typename... Args>
|
||||
constexpr int sums (T i, Args... args) {
|
||||
return i + sums(args...);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Wrapper public.
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
|
|||
166
include/linphone/utils/static-string.h
Normal file
166
include/linphone/utils/static-string.h
Normal file
|
|
@ -0,0 +1,166 @@
|
|||
/*
|
||||
* 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<std::size_t...>
|
||||
struct IndexSequence {
|
||||
using Type = IndexSequence;
|
||||
};
|
||||
|
||||
namespace Private {
|
||||
template<typename S1, typename S2>
|
||||
struct ConcatIndexSequenceImpl;
|
||||
|
||||
template<std::size_t... S1, std::size_t... S2>
|
||||
struct ConcatIndexSequenceImpl<IndexSequence<S1...>, IndexSequence<S2...>> :
|
||||
IndexSequence<S1..., (sizeof...(S1) + S2)...> {};
|
||||
|
||||
template<std::size_t N>
|
||||
struct MakeIndexSequenceImpl : ConcatIndexSequenceImpl<
|
||||
typename MakeIndexSequenceImpl<N / 2>::Type,
|
||||
typename MakeIndexSequenceImpl<N - N / 2>::Type
|
||||
> {};
|
||||
|
||||
template<>
|
||||
struct MakeIndexSequenceImpl<0> : IndexSequence<> {};
|
||||
|
||||
template<>
|
||||
struct MakeIndexSequenceImpl<1> : IndexSequence<0> {};
|
||||
}
|
||||
|
||||
template<std::size_t N>
|
||||
using MakeIndexSequence = typename Private::MakeIndexSequenceImpl<N>::Type;
|
||||
|
||||
// =============================================================================
|
||||
|
||||
// See: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4121.pdf
|
||||
template<std::size_t N>
|
||||
using RawStaticString = const char [N];
|
||||
|
||||
namespace Private {
|
||||
template<std::size_t N, typename = MakeIndexSequence<N>>
|
||||
struct StaticString;
|
||||
|
||||
template<std::size_t N, std::size_t... Index>
|
||||
struct StaticString<N, IndexSequence<Index...>> {
|
||||
constexpr StaticString (const RawStaticString<N> &inRaw) : raw{ (inRaw[Index])... } {}
|
||||
|
||||
constexpr char operator[] (std::size_t i) const {
|
||||
return raw[i];
|
||||
}
|
||||
|
||||
constexpr operator const char * () const {
|
||||
return raw;
|
||||
}
|
||||
|
||||
RawStaticString<N> raw;
|
||||
};
|
||||
|
||||
template<std::size_t N>
|
||||
class StaticStringConcatHelper {
|
||||
public:
|
||||
template<std::size_t N1>
|
||||
constexpr StaticStringConcatHelper(
|
||||
const Private::StaticString<N1> &s1,
|
||||
const Private::StaticString<N - N1 + 1> &s2
|
||||
) : StaticStringConcatHelper(s1, s2, MakeIndexSequence<N1 - 1>{}, MakeIndexSequence<N - N1 + 1>{}) {}
|
||||
|
||||
RawStaticString<N> raw;
|
||||
|
||||
private:
|
||||
template<std::size_t N1, std::size_t... Index1, std::size_t... Index2>
|
||||
constexpr StaticStringConcatHelper(
|
||||
const Private::StaticString<N1> &s1,
|
||||
const Private::StaticString<N - N1 + 1> &s2,
|
||||
IndexSequence<Index1...>,
|
||||
IndexSequence<Index2...>
|
||||
) : raw{ s1[Index1]..., s2[Index2]... } {}
|
||||
};
|
||||
|
||||
template<int Value, int N = getIntLength(Value) + 1>
|
||||
class StaticIntStringHelper {
|
||||
public:
|
||||
constexpr StaticIntStringHelper () : StaticIntStringHelper(MakeIndexSequence<Value >= 0 ? N - 1 : N - 2>{}) {}
|
||||
|
||||
RawStaticString<N> raw;
|
||||
|
||||
private:
|
||||
template<std::size_t... Index, typename Int = int, typename std::enable_if<Int(Value) >= 0, int>::type* = nullptr>
|
||||
constexpr StaticIntStringHelper (const IndexSequence<Index...> &) :
|
||||
raw{ ('0' + Value / pow10(N - Index - 2) % 10 )..., '\0' } {}
|
||||
|
||||
template<std::size_t... Index, typename Int = int, typename std::enable_if<Int(Value) < 0, int>::type* = nullptr>
|
||||
constexpr StaticIntStringHelper (const IndexSequence<Index...> &) :
|
||||
raw{ '-', ('0' + abs(Value) / pow10(N - Index - 3) % 10 )..., '\0' } {}
|
||||
};
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
template<std::size_t N>
|
||||
constexpr Private::StaticString<N> StaticString (const RawStaticString<N> &raw) {
|
||||
return Private::StaticString<N>(raw);
|
||||
}
|
||||
|
||||
template<std::size_t N1, std::size_t N2>
|
||||
constexpr Private::StaticString<N1 + N2 - 1> operator+ (
|
||||
const Private::StaticString<N1> &s1,
|
||||
const Private::StaticString<N2> &s2
|
||||
) {
|
||||
return StaticString(Private::StaticStringConcatHelper<N1 + N2 - 1>(s1, s2).raw);
|
||||
}
|
||||
|
||||
template<std::size_t N1, std::size_t N2>
|
||||
constexpr Private::StaticString<N1 + N2 - 1> operator+ (
|
||||
const Private::StaticString<N1> &s1,
|
||||
const RawStaticString<N2> &s2
|
||||
) {
|
||||
return StaticString(Private::StaticStringConcatHelper<N1 + N2 - 1>(s1, StaticString(s2)).raw);
|
||||
}
|
||||
|
||||
template<std::size_t N1, std::size_t N2>
|
||||
constexpr Private::StaticString<N1 + N2 - 1> operator+ (
|
||||
const RawStaticString<N2> &s1,
|
||||
const Private::StaticString<N1> &s2
|
||||
) {
|
||||
return StaticString(Private::StaticStringConcatHelper<N1 + N2 - 1>(StaticString(s1), s2).raw);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
template<int Value = 0>
|
||||
constexpr Private::StaticString<getIntLength(Value) + 1> StaticIntString () {
|
||||
return StaticString(Private::StaticIntStringHelper<Value>().raw);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
LINPHONE_END_NAMESPACE
|
||||
|
||||
#endif // ifndef _L_STATIC_STRING_H_
|
||||
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
#include "linphone/utils/algorithm.h"
|
||||
#include "linphone/utils/utils.h"
|
||||
#include "linphone/utils/static-string.h"
|
||||
|
||||
#include "chat/chat-message/chat-message-p.h"
|
||||
#include "chat/chat-room/chat-room-p.h"
|
||||
|
|
@ -94,9 +95,10 @@ MainDb::MainDb (const shared_ptr<Core> &core) : AbstractDb(*new MainDbPrivate),
|
|||
#ifdef SOCI_ENABLED
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Soci backend.
|
||||
// Event filter tools.
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// Some tools to build filters at compile time.
|
||||
template<typename T>
|
||||
struct EnumToSql {
|
||||
T first;
|
||||
|
|
@ -110,17 +112,61 @@ static constexpr const char *mapEnumToSql (const EnumToSql<T> enumToSql[], size_
|
|||
);
|
||||
}
|
||||
|
||||
// Update me event-log-enums values are changed!
|
||||
static constexpr EnumToSql<MainDb::Filter> eventFilterToSql[] = {
|
||||
{ MainDb::ConferenceCallFilter, "3, 4" },
|
||||
{ MainDb::ConferenceChatMessageFilter, "5" },
|
||||
{ MainDb::ConferenceInfoFilter, "1, 2, 6, 7, 8, 9, 10, 11, 12" },
|
||||
{ MainDb::ConferenceInfoNoDeviceFilter, "1, 2, 6, 7, 8, 9, 12" }
|
||||
template<EventLog::Type ...Type>
|
||||
struct SqlEventFilterBuilder {};
|
||||
|
||||
template<EventLog::Type Type, EventLog::Type... List>
|
||||
struct SqlEventFilterBuilder<Type, List...> {
|
||||
static constexpr Private::StaticString<1 + getIntLength(int(Type)) + sums((1 + getIntLength(int(List)))...)> get () {
|
||||
return StaticIntString<int(Type)>() + "," + SqlEventFilterBuilder<List...>::get();
|
||||
}
|
||||
};
|
||||
|
||||
static constexpr const char *mapEventFilterToSql (MainDb::Filter filter) {
|
||||
template<EventLog::Type Type>
|
||||
struct SqlEventFilterBuilder<Type> {
|
||||
static constexpr Private::StaticString<1 + getIntLength(int(Type))> get () {
|
||||
return StaticIntString<int(Type)>();
|
||||
}
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Event filters.
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
namespace {
|
||||
constexpr auto ConferenceCallFilter = SqlEventFilterBuilder<
|
||||
EventLog::Type::ConferenceCallStart,
|
||||
EventLog::Type::ConferenceCallEnd
|
||||
>::get();
|
||||
|
||||
constexpr auto ConferenceChatMessageFilter = SqlEventFilterBuilder<EventLog::Type::ConferenceChatMessage>::get();
|
||||
|
||||
constexpr auto ConferenceInfoNoDeviceFilter = SqlEventFilterBuilder<
|
||||
EventLog::Type::ConferenceCreated,
|
||||
EventLog::Type::ConferenceTerminated,
|
||||
EventLog::Type::ConferenceParticipantAdded,
|
||||
EventLog::Type::ConferenceParticipantRemoved,
|
||||
EventLog::Type::ConferenceParticipantSetAdmin,
|
||||
EventLog::Type::ConferenceParticipantUnsetAdmin,
|
||||
EventLog::Type::ConferenceSubjectChanged
|
||||
>::get();
|
||||
|
||||
constexpr auto ConferenceInfoFilter = ConferenceInfoNoDeviceFilter + "," + SqlEventFilterBuilder<
|
||||
EventLog::Type::ConferenceParticipantDeviceAdded,
|
||||
EventLog::Type::ConferenceParticipantDeviceRemoved
|
||||
>::get();
|
||||
|
||||
constexpr EnumToSql<MainDb::Filter> EventFilterToSql[] = {
|
||||
{ MainDb::ConferenceCallFilter, ConferenceCallFilter },
|
||||
{ MainDb::ConferenceChatMessageFilter, ConferenceChatMessageFilter },
|
||||
{ MainDb::ConferenceInfoNoDeviceFilter, ConferenceInfoNoDeviceFilter },
|
||||
{ MainDb::ConferenceInfoFilter, ConferenceInfoFilter }
|
||||
};
|
||||
}
|
||||
|
||||
static const char *mapEventFilterToSql (MainDb::Filter filter) {
|
||||
return mapEnumToSql(
|
||||
eventFilterToSql, sizeof eventFilterToSql / sizeof eventFilterToSql[0], filter
|
||||
EventFilterToSql, sizeof EventFilterToSql / sizeof EventFilterToSql[0], filter
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue