base/include: use C++20 function template syntax

Issue #5227
This commit is contained in:
Norman Feske 2024-05-22 16:35:38 +02:00 committed by Christian Helmuth
parent 48d6f0220c
commit 5e862b2cd3
38 changed files with 173 additions and 254 deletions

View File

@ -26,7 +26,7 @@ namespace Genode {
struct Allocator;
struct Range_allocator;
template <typename T, typename DEALLOC> void destroy(DEALLOC && dealloc, T *obj);
template <typename T> void destroy(auto && dealloc, T *obj);
}
@ -276,8 +276,8 @@ inline void operator delete (void *ptr, Genode::Allocator &a) {
* was allocated
* \param obj object to destroy
*/
template <typename T, typename DEALLOC>
void Genode::destroy(DEALLOC && dealloc, T *obj)
template <typename T>
void Genode::destroy(auto && dealloc, T *obj)
{
if (!obj)
return;

View File

@ -207,11 +207,9 @@ class Genode::Allocator_avl_base : public Range_allocator
*/
void _cut_from_block(Block &b, addr_t cut_addr, size_t cut_size, Two_blocks);
template <typename ANY_BLOCK_FN>
bool _revert_block_ranges(ANY_BLOCK_FN const &);
bool _revert_block_ranges(auto const &any_block_fn);
template <typename SEARCH_FN>
Alloc_result _allocate(size_t, unsigned, Range, SEARCH_FN const &);
Alloc_result _allocate(size_t, unsigned, Range, auto const &search_fn);
protected:
@ -427,8 +425,7 @@ class Genode::Allocator_avl_tpl : public Allocator_avl_base
* the method repeatedly without removing or inserting
* members will produce the same member.
*/
template <typename FUNC>
bool apply_any(FUNC const &fn)
bool apply_any(auto const &fn)
{
addr_t addr = 0;
if (any_block_addr(&addr)) {

View File

@ -214,9 +214,10 @@ struct Genode::Child_policy
* the case for a debug monitor - the address space must be accessed by
* component-local method calls instead.
*/
template <typename FN>
void with_address_space(Pd_session &pd, FN const &fn)
void with_address_space(Pd_session &pd, auto const &fn)
{
using FN = decltype(fn);
struct Impl : With_address_space_fn
{
FN const &_fn;
@ -323,8 +324,7 @@ class Genode::Child : protected Rpc_object<Parent>,
Child_policy &_policy;
/* print error message with the child's name prepended */
template <typename... ARGS>
void _error(ARGS &&... args) { error(_policy.name(), ": ", args...); }
void _error(auto &&... args) { error(_policy.name(), ": ", args...); }
Region_map &_local_rm;
@ -786,8 +786,7 @@ class Genode::Child : protected Rpc_object<Parent>,
void close_all_sessions();
template <typename FN>
void for_each_session(FN const &fn) const
void for_each_session(auto const &fn) const
{
_id_space.for_each<Session_state const>(fn);
}

View File

@ -71,14 +71,13 @@ class Genode::Connection_base : Noncopyable, Interface
*
* \noapi
*/
template <typename FUNC>
auto retry_with_upgrade(Ram_quota ram, Cap_quota caps, FUNC func) -> decltype(func())
auto retry_with_upgrade(Ram_quota ram, Cap_quota caps, auto const &fn) -> decltype(fn())
{
enum { UPGRADE_ATTEMPTS = ~0U };
return Genode::retry<Out_of_ram>(
[&] () {
return Genode::retry<Out_of_caps>(
[&] () { return func(); },
[&] () { return fn(); },
[&] () { upgrade_caps(caps.value); },
UPGRADE_ATTEMPTS);
},

View File

@ -148,8 +148,7 @@ class Genode::Heap : public Allocator
/**
* Call 'fn' with the start and size of each backing-store region
*/
template <typename FN>
void for_each_region(FN const &fn) const
void for_each_region(auto const &fn) const
{
Mutex::Guard guard(_mutex);
for (Dataspace const *ds = _ds_pool.first(); ds; ds = ds->next())

View File

@ -63,8 +63,8 @@ class Genode::Id_space : public Noncopyable
return e ? e->_lookup(id) : 0;
}
template <typename ARG, typename FUNC>
void _for_each(FUNC const &fn) const
template <typename ARG>
void _for_each(auto const &fn) const
{
if (Avl_node<Element>::child(Avl_node_base::LEFT))
Avl_node<Element>::child(Avl_node_base::LEFT)->template _for_each<ARG>(fn);
@ -173,8 +173,8 @@ class Genode::Id_space : public Noncopyable
* This function is called with the ID space locked. Hence, it is not
* possible to modify the ID space from within 'fn'.
*/
template <typename ARG, typename FUNC>
void for_each(FUNC const &fn) const
template <typename ARG>
void for_each(auto const &fn) const
{
Mutex::Guard guard(_mutex);
@ -189,9 +189,9 @@ class Genode::Id_space : public Noncopyable
*
* \throw Unknown_id
*/
template <typename ARG, typename FUNC>
auto apply(Id id, FUNC const &fn)
-> typename Trait::Functor<decltype(&FUNC::operator())>::Return_type
template <typename ARG, typename FN>
auto apply(Id id, FN const &fn)
-> typename Trait::Functor<decltype(&FN::operator())>::Return_type
{
T *obj = nullptr;
{
@ -222,8 +222,8 @@ class Genode::Id_space : public Noncopyable
* \return true if 'fn' was applied, or
* false if the ID space is empty.
*/
template <typename ARG, typename FUNC>
bool apply_any(FUNC const &fn)
template <typename ARG>
bool apply_any(auto const &fn)
{
T *obj = nullptr;
{

View File

@ -58,8 +58,7 @@ class Genode::Log
Log(Output &output) : _output(output) { }
template <typename... ARGS>
void output(Type type, ARGS &&... args)
void output(Type type, auto &&... args)
{
/*
* This function is being inlined. Hence, we try to keep it as
@ -82,8 +81,7 @@ class Genode::Log
*/
struct Log_fn
{
template <typename... ARGS>
Log_fn(ARGS && ... args) { log().output(LOG, args...); }
Log_fn(auto && ... args) { log().output(LOG, args...); }
};
};
@ -103,8 +101,7 @@ class Genode::Raw
public:
template <typename... ARGS>
static void output(ARGS &&... args)
static void output(auto &&... args)
{
_acquire();
Output::out_args(_output(), args...);
@ -132,8 +129,7 @@ class Genode::Trace_output
Trace_output() { }
template <typename... ARGS>
void output(ARGS &&... args)
void output(auto &&... args)
{
Buffered_trace_output buffered_trace_output
{ Write_trace_fn() };
@ -152,8 +148,7 @@ class Genode::Trace_output
*/
struct Fn
{
template <typename... ARGS>
Fn(ARGS && ... args)
Fn(auto && ... args)
{
trace_output().output(Trace::timestamp(), ": ", args...);
}
@ -166,8 +161,7 @@ namespace Genode {
/**
* Write 'args' as a regular message to the log
*/
template <typename... ARGS>
void log(ARGS &&... args) { Log::Log_fn(args...); }
void log(auto &&... args) { Log::Log_fn(args...); }
/**
@ -177,8 +171,7 @@ namespace Genode {
* the description of the 'error' function regarding the convention of
* formatting error/warning messages.
*/
template <typename... ARGS>
void warning(ARGS &&... args) { Log::log().output(Log::WARNING, args...); }
void warning(auto &&... args) { Log::log().output(Log::WARNING, args...); }
/**
@ -189,8 +182,7 @@ namespace Genode {
* message. By convention, the actual message should be brief, starting
* with a lower-case character.
*/
template <typename... ARGS>
void error(ARGS &&... args) { Log::log().output(Log::ERROR, args...); }
void error(auto &&... args) { Log::log().output(Log::ERROR, args...); }
/**
@ -198,8 +190,7 @@ namespace Genode {
*
* This function is intended for temporarily debugging purposes only.
*/
template <typename... ARGS>
void raw(ARGS &&... args) { Raw::output(args...); }
void raw(auto &&... args) { Raw::output(args...); }
/**
@ -207,8 +198,7 @@ namespace Genode {
*
* The message is prefixed with a timestamp value
*/
template <typename... ARGS>
void trace(ARGS && ... args) { Trace_output::Fn(args...); }
void trace(auto && ... args) { Trace_output::Fn(args...); }
}

View File

@ -120,11 +120,11 @@ class Genode::Object_pool : Interface, Noncopyable
_tree.remove(obj);
}
template <typename FUNC>
auto apply(unsigned long capid, FUNC func)
-> typename Trait::Functor<decltype(&FUNC::operator())>::Return_type
template <typename FN>
auto apply(unsigned long capid, FN const &fn)
-> typename Trait::Functor<decltype(&FN::operator())>::Return_type
{
using Functor = Trait::Functor<decltype(&FUNC::operator())>;
using Functor = Trait::Functor<decltype(&FN::operator())>;
using Object_pointer = typename Functor::template Argument<0>::Type;
using Weak_ptr = Weak_ptr<typename Entry::Entry_lock>;
using Locked_ptr = Locked_ptr<typename Entry::Entry_lock>;
@ -144,19 +144,18 @@ class Genode::Object_pool : Interface, Noncopyable
Locked_ptr lock_ptr(ptr);
Object_pointer op = lock_ptr.valid()
? dynamic_cast<Object_pointer>(&lock_ptr->obj) : nullptr;
return func(op);
return fn(op);
}
}
template <typename FUNC>
auto apply(Untyped_capability cap, FUNC func)
-> typename Trait::Functor<decltype(&FUNC::operator())>::Return_type
template <typename FN>
auto apply(Untyped_capability cap, FN const &fn)
-> typename Trait::Functor<decltype(&FN::operator())>::Return_type
{
return apply(cap.local_name(), func);
return apply(cap.local_name(), fn);
}
template <typename FUNC>
void remove_all(FUNC func)
void remove_all(auto const &fn)
{
using Weak_ptr = Weak_ptr<typename Entry::Entry_lock>;
using Locked_ptr = Locked_ptr<typename Entry::Entry_lock>;
@ -178,7 +177,7 @@ class Genode::Object_pool : Interface, Noncopyable
}
}
func(obj);
fn(obj);
}
}
};

View File

@ -43,15 +43,13 @@ struct Genode::Output : Interface
/**
* Helper for the sequential output of a variable list of arguments
*/
template <typename HEAD, typename... TAIL>
static void out_args(Output &output, HEAD && head, TAIL &&... tail)
static void out_args(Output &output, auto && head, auto &&... tail)
{
print(output, head);
out_args(output, tail...);
}
template <typename LAST>
static void out_args(Output &output, LAST && last) { print(output, last); }
static void out_args(Output &output, auto && last) { print(output, last); }
};
@ -82,8 +80,7 @@ namespace Genode {
* This function template takes precedence over the one that takes a
* constant object reference as argument.
*/
template <typename T>
static inline void print(Output &output, T *ptr)
static inline void print(Output &output, auto *ptr)
{
print(output, (void const *)ptr);
}
@ -173,9 +170,8 @@ namespace Genode {
* output. If set to 'PAD', the leading zeros will be
* printed.
*/
template <typename T>
explicit Hex(T value, Prefix prefix = PREFIX, Pad pad = NO_PAD)
: _value(value), _digits(2*sizeof(T)), _prefix(prefix), _pad(pad) { }
explicit Hex(auto value, Prefix prefix = PREFIX, Pad pad = NO_PAD)
: _value(value), _digits(2*sizeof(value)), _prefix(prefix), _pad(pad) { }
void print(Output &output) const;
};
@ -224,8 +220,7 @@ namespace Genode {
* method is able to access object-internal state, which can thereby be
* incorporated into the textual output.
*/
template <typename T>
static inline void print(Output &output, T const &obj)
static inline void print(Output &output, auto const &obj)
{
obj.print(output);
}
@ -233,8 +228,7 @@ namespace Genode {
/**
* Print a variable number of arguments
*/
template <typename HEAD, typename... TAIL>
static inline void print(Output &output, HEAD const &head, TAIL &&... tail)
static inline void print(Output &output, auto const &head, auto &&... tail)
{
Output::out_args(output, head, tail...);
}

View File

@ -250,10 +250,10 @@ class Genode::Quota_guard
void acknowledge() { _ack = true; }
};
template <typename RET, typename FN, typename ERROR_FN>
RET with_reservation(UNIT const amount,
FN const &fn,
ERROR_FN const &error_fn)
template <typename RET>
RET with_reservation(UNIT const amount,
auto const &fn,
auto const &error_fn)
{
if (!_guard.try_withdraw(amount.value))
return error_fn();

View File

@ -109,13 +109,14 @@ struct Genode::Registry : private Registry_base
: Registry_base::Element(registry, &obj) { }
};
template <typename FUNC>
void for_each(FUNC const &fn)
void for_each(auto const &fn)
{
using FN = decltype(fn);
struct Typed_functor : Registry_base::Untyped_functor
{
FUNC const &_fn;
Typed_functor(FUNC const &fn) : _fn(fn) { }
FN const &_fn;
Typed_functor(FN const &fn) : _fn(fn) { }
void call(void *obj_ptr) override
{
@ -127,8 +128,7 @@ struct Genode::Registry : private Registry_base
Registry_base::_for_each(untyped_functor);
}
template <typename FUNC>
void for_each(FUNC const &fn) const
void for_each(auto const &fn) const
{
Mutex::Guard guard(_mutex);
@ -170,8 +170,7 @@ class Genode::Registered : public T
*/
static_assert(__has_virtual_destructor(T), "registered object must have virtual destructor");
template <typename... ARGS>
Registered(Registry<Registered<T> > &registry, ARGS &&... args)
Registered(Registry<Registered<T> > &registry, auto &&... args)
: T(args...), _element(registry, *this) { }
};
@ -193,8 +192,7 @@ class Genode::Registered_no_delete : public T
public:
template <typename... ARGS>
Registered_no_delete(Registry<Registered_no_delete<T> > &registry, ARGS &&... args)
Registered_no_delete(Registry<Registered_no_delete<T> > &registry, auto &&... args)
: T(args...), _element(registry, *this) { }
};

View File

@ -77,8 +77,7 @@ class Genode::Service : public Ram_transfer::Account,
* session state. All subsequent 'Session_state' arguments correspond
* to the forwarded 'args'.
*/
template <typename... ARGS>
Session_state &create_session(Factory &client_factory, ARGS &&... args)
Session_state &create_session(Factory &client_factory, auto &&... args)
{
return _factory(client_factory).create(*this, args...);
}
@ -151,8 +150,7 @@ class Genode::Local_service : public Service
Factory &_factory;
template <typename FUNC>
void _apply_to_rpc_obj(Session_state &session, FUNC const &fn)
void _apply_to_rpc_obj(Session_state &session, auto const &fn)
{
SESSION *rpc_obj = dynamic_cast<SESSION *>(session.local_ptr);

View File

@ -101,8 +101,7 @@ class Genode::Session_object : private Ram_quota_guard,
* The method produces output only if the session is in diagnostic
* mode (defined via the 'diag' session argument).
*/
template <typename... ARGS>
void diag(ARGS &&... args) const
void diag(auto &&... args) const
{
if (_diag.enabled)
log(RPC_INTERFACE::service_name(), " (", _label, ") ", args...);
@ -111,8 +110,7 @@ class Genode::Session_object : private Ram_quota_guard,
/**
* Output label-prefixed error message
*/
template <typename... ARGS>
void error(ARGS &&... args) const
void error(auto &&... args) const
{
Genode::error(RPC_INTERFACE::service_name(), " (", _label, ") ", args...);
}
@ -120,8 +118,7 @@ class Genode::Session_object : private Ram_quota_guard,
/**
* Output label-prefixed error message
*/
template <typename... ARGS>
void warning(ARGS &&... args) const
void warning(auto &&... args) const
{
Genode::warning(RPC_INTERFACE::service_name(), " (", _label, ") ", args...);
}

View File

@ -323,8 +323,7 @@ class Genode::Session_state::Factory : Noncopyable
*
* \throw Allocator::Out_of_memory
*/
template <typename... ARGS>
Session_state &create(ARGS &&... args)
Session_state &create(auto &&... args)
{
Session_state &session = *new (_slab) Session_state(args...);
session.owner(*this);

View File

@ -301,15 +301,16 @@ class Genode::Signal_receiver : Noncopyable
void remove(Signal_context const *re);
template <typename FUNC>
void for_each_locked(FUNC && functor) const
void for_each_locked(auto const &fn) const
{
Signal_context *context = _head;
if (!context) return;
if (!context)
return;
do {
Mutex::Guard mutex_guard(context->_mutex);
if (functor(*context)) return;
if (fn(*context))
return;
context = context->_next;
} while (context != _head);
}

View File

@ -44,8 +44,7 @@ class Genode::Synced_allocator : public Allocator
using Guard = typename Synced_interface<ALLOC, Mutex>::Guard;
template <typename... ARGS>
Synced_allocator(ARGS &&... args)
Synced_allocator(auto &&... args)
: _alloc(args...), _synced_object(_mutex, &_alloc) { }
Guard operator () () { return _synced_object(); }

View File

@ -421,8 +421,7 @@ class Genode::Thread
/**
* Log trace event as defined in base/trace/events.h
*/
template <typename EVENT>
static void trace(EVENT const *event) { _logger()->log(event); }
static void trace(auto const *event) { _logger()->log(event); }
/**
* Thread affinity

View File

@ -160,8 +160,7 @@ class Genode::Trace::Simple_buffer
_head_entry()->mark(_Entry::HEAD);
}
template <typename WRAP_FUNC>
char *_reserve(size_t len, WRAP_FUNC && wrap)
char *_reserve(size_t len, auto const &wrap_fn)
{
if (_head_offset + sizeof(_Entry) + len <= _size)
return _head_entry()->data;
@ -170,11 +169,10 @@ class Genode::Trace::Simple_buffer
if (_head_offset + sizeof(_Entry) <= _size)
_head_entry()->mark(_Entry::PADDING);
return wrap();
return wrap_fn();
}
template <typename WRAP_FUNC>
void _commit(size_t len, WRAP_FUNC && wrap)
void _commit(size_t len, auto const &wrap_fn)
{
/* omit empty entries */
if (len == 0)
@ -190,7 +188,7 @@ class Genode::Trace::Simple_buffer
/* advance head offset, wrap when next entry does not fit into buffer */
_head_offset += sizeof(_Entry) + len;
if (_head_offset + sizeof(_Entry) > _size)
wrap();
wrap_fn();
/* mark entry next to new entry as head */
else if (_head_offset + sizeof(_Entry) <= _size)

View File

@ -77,9 +77,8 @@ struct Genode::Trace::Logger
/**
* Log event to trace buffer
*/
template <typename EVENT>
__attribute__((optimize("-fno-delete-null-pointer-checks")))
void log(EVENT const *event)
void log(auto const *event)
{
if (!this || !_evaluate_control()) return;

View File

@ -53,8 +53,8 @@ class Genode::Page_table_allocator
virtual ~Page_table_allocator() { }
template <typename TABLE, typename FN1, typename FN2>
void with_table(addr_t phys_addr, FN1 && match_fn, FN2 no_match_fn)
template <typename TABLE>
void with_table(addr_t phys_addr, auto const &match_fn, auto const &no_match_fn)
{
static_assert((sizeof(TABLE) == TABLE_SIZE), "unexpected size");
@ -108,8 +108,7 @@ class Genode::Page_table_allocator<TABLE_SIZE>::Array
Array() : _alloc((Table*)&_tables, (addr_t)&_tables, COUNT * TABLE_SIZE) {}
template <typename T>
explicit Array(T phys_addr)
explicit Array(auto phys_addr)
: _alloc(_tables, phys_addr((void*)_tables), COUNT * TABLE_SIZE) { }
Page_table_allocator<TABLE_SIZE> & alloc() { return _alloc; }

View File

@ -73,8 +73,7 @@ struct Genode::Region_map : Interface
public:
template <typename T>
Local_addr(T ptr) : _ptr((void *)ptr) { }
Local_addr(auto ptr) : _ptr((void *)ptr) { }
Local_addr() { }

View File

@ -225,14 +225,9 @@ class Genode::Vcpu_state
bool charged() const { return _charged; }
template <typename FN>
void with_state(FN const &fn) const
{
fn(_state);
}
void with_state(auto const &fn) const { fn(_state); }
template <typename FN>
void charge(FN const &fn)
void charge(auto const &fn)
{
_charged = true;
fn(_state);

View File

@ -88,8 +88,7 @@ struct Genode::Trace::Session_client : Genode::Rpc_client<Genode::Trace::Session
struct For_each_subject_info_result { size_t count; size_t limit; };
template <typename FN>
For_each_subject_info_result for_each_subject_info(FN const &fn)
For_each_subject_info_result for_each_subject_info(auto const &fn)
{
size_t const num_subjects = call<Rpc_subject_infos>();
size_t const max_subjects = _argument_buffer.size / (sizeof(Subject_info) + sizeof(Subject_id));

View File

@ -24,10 +24,9 @@ namespace Genode { namespace Trace { struct Connection; } }
struct Genode::Trace::Connection : Genode::Connection<Genode::Trace::Session>,
Genode::Trace::Session_client
{
template <typename FUNC>
auto _retry(FUNC func) -> decltype(func())
auto _retry(auto const &fn) -> decltype(fn())
{
return retry_with_upgrade(Ram_quota{8*1024}, Cap_quota{2}, func);
return retry_with_upgrade(Ram_quota{8*1024}, Cap_quota{2}, fn);
}
/**
@ -60,8 +59,7 @@ struct Genode::Trace::Connection : Genode::Connection<Genode::Trace::Session>,
return Session_client::subjects(dst, dst_len); });
}
template <typename FN>
For_each_subject_info_result for_each_subject_info(FN const &fn)
For_each_subject_info_result for_each_subject_info(auto const &fn)
{
return _retry([&] () {
return Session_client::for_each_subject_info(fn); });

View File

@ -99,26 +99,23 @@ class Genode::Array
*
* \throw Index_out_of_bounds
*/
template<typename ... TAIL>
void add(T obj, TAIL ... tail)
void add(T obj, auto &&... tail)
{
add(obj);
add(tail...);
}
template <typename FUNC>
void for_each(FUNC const &f)
void for_each(auto const &fn)
{
for (unsigned idx = 0; idx < _count; idx++)
f(idx, _objs[idx]);
fn(idx, _objs[idx]);
}
template <typename FUNC>
void for_each(FUNC const &f) const
void for_each(auto const &fn) const
{
for (unsigned idx = 0; idx < _count; idx++) {
T const & obj = _objs[idx];
f(idx, obj);
fn(idx, obj);
}
}
};

View File

@ -52,21 +52,19 @@ class Genode::Attempt
Attempt(Attempt const &) = default;
Attempt &operator = (Attempt const &) = default;
template <typename RET, typename ACCESS_FN, typename FAIL_FN>
RET convert(ACCESS_FN const &access_fn, FAIL_FN const &fail_fn) const
template <typename RET>
RET convert(auto const &access_fn, auto const &fail_fn) const
{
return _ok ? RET { access_fn(_result) }
: RET { fail_fn(_error) };
}
template <typename ACCESS_FN, typename FAIL_FN>
void with_result(ACCESS_FN const &access_fn, FAIL_FN const &fail_fn) const
void with_result(auto const &access_fn, auto const &fail_fn) const
{
_ok ? access_fn(_result) : fail_fn(_error);
}
template <typename FAIL_FN>
void with_error(FAIL_FN const &fail_fn) const
void with_error(auto const &fail_fn) const
{
if (!_ok)
fail_fn(_error);

View File

@ -168,14 +168,13 @@ struct Genode::Avl_node : Avl_node_base
/**
* Apply a functor (read-only) to every node within this subtree
*
* \param functor function that takes a const NT reference
* \param fn function that takes a const NT reference
*/
template <typename FUNC>
void for_each(FUNC && functor) const
void for_each(auto const &fn) const
{
if (NT * l = child(Avl_node<NT>::LEFT)) l->for_each(functor);
functor(*static_cast<NT const *>(this));
if (NT * r = child(Avl_node<NT>::RIGHT)) r->for_each(functor);
if (NT * l = child(Avl_node<NT>::LEFT)) l->for_each(fn);
fn(*static_cast<NT const *>(this));
if (NT * r = child(Avl_node<NT>::RIGHT)) r->for_each(fn);
}
};
@ -229,13 +228,12 @@ class Genode::Avl_tree : Avl_node<NT>
/**
* Apply a functor (read-only) to every node within the tree
*
* \param functor function that takes a const NT reference
* \param fn function that takes a const NT reference
*
* The iteration order corresponds to the order of the keys
*/
template <typename FUNC>
void for_each(FUNC && functor) const {
if (first()) first()->for_each(functor); }
void for_each(auto const &fn) const {
if (first()) first()->for_each(fn); }
};
#endif /* _INCLUDE__UTIL__AVL_TREE_H_ */

View File

@ -17,7 +17,7 @@
#include <util/bit_array.h>
namespace Genode { template<unsigned> class Bit_allocator; }
namespace Genode { template<unsigned> class Bit_allocator; }
template<unsigned BITS>

View File

@ -81,9 +81,9 @@ class Genode::Dictionary : Noncopyable
* matching dictionary element. If no maching element exists,
* 'no_match_fn' is called without argument.
*/
template <typename FN1, typename FN2>
auto with_element(NAME const &name, FN1 const &match_fn, FN2 const &no_match_fn)
-> typename Trait::Functor<decltype(&FN1::operator())>::Return_type
template <typename FN>
auto with_element(NAME const &name, FN const &match_fn, auto const &no_match_fn)
-> typename Trait::Functor<decltype(&FN::operator())>::Return_type
{
T *curr_ptr = _tree.first();
for (;;) {
@ -106,9 +106,9 @@ class Genode::Dictionary : Noncopyable
* matching dictionary element. If no maching element exists,
* 'no_match_fn' is called without argument.
*/
template <typename FN1, typename FN2>
auto with_element(NAME const &name, FN1 const &match_fn, FN2 const &no_match_fn) const
-> typename Trait::Functor<decltype(&FN1::operator())>::Return_type
template <typename FN>
auto with_element(NAME const &name, FN const &match_fn, auto const &no_match_fn) const
-> typename Trait::Functor<decltype(&FN::operator())>::Return_type
{
auto const_match_fn = [&] (T const &e) { return match_fn(e); };
auto non_const_this = const_cast<Dictionary *>(this);
@ -124,8 +124,7 @@ class Genode::Dictionary : Noncopyable
* This method is intended for the orderly destruction of a dictionary.
* It allows for the consecutive destruction of all elements.
*/
template <typename FUNC>
bool with_any_element(FUNC const &fn)
bool with_any_element(auto const &fn)
{
T *curr_ptr = _tree.first();
if (!curr_ptr)
@ -135,8 +134,7 @@ class Genode::Dictionary : Noncopyable
return true;
}
template <typename FN>
void for_each(FN const &fn) const { _tree.for_each(fn); }
void for_each(auto const &fn) const { _tree.for_each(fn); }
bool exists(NAME const &name) const
{

View File

@ -75,10 +75,9 @@ class Genode::Fifo
Fifo() { }
/**
* Call 'func' of type 'void (QT&)' the head element
* Call 'fn' of type 'void (QT&)' the head element
*/
template <typename FUNC>
void head(FUNC const &func) const { if (_head) func(*_head); }
void head(auto const &fn) const { if (_head) fn(*_head); }
/**
* Remove element explicitly from queue
@ -130,25 +129,23 @@ class Genode::Fifo
}
/**
* Call 'func' of type 'void (QT&)' for each element in order
* Call 'fn' of type 'void (QT&)' for each element in order
*/
template <typename FUNC>
void for_each(FUNC const &func) const
void for_each(auto const &fn) const
{
QT *elem = _head;
while (elem != nullptr) {
/* take the next pointer so 'func' cannot modify it */
/* take the next pointer so 'fn' cannot modify it */
QT *next = elem->Fifo::Element::_next;;
func(*elem);
fn(*elem);
elem = next;
}
}
/**
* Remove head and call 'func' of type 'void (QT&)'
* Remove head and call 'fn' of type 'void (QT&)'
*/
template <typename FUNC>
void dequeue(FUNC const &func)
void dequeue(auto const &fn)
{
QT *result = _head;
@ -165,7 +162,7 @@ class Genode::Fifo
result->Fifo::Element::_enqueued = false;
/* pass to caller */
func(*result);
fn(*result);
}
}
@ -173,13 +170,12 @@ class Genode::Fifo
* Remove all fifo elements
*
* This method removes all elements in order and calls the lambda
* 'func' of type 'void (QT&)' for each element. It is intended to be
* 'fn' of type 'void (QT&)' for each element. It is intended to be
* used prior the destruction of the FIFO.
*/
template <typename FUNC>
void dequeue_all(FUNC const &func)
void dequeue_all(auto const &fn)
{
while (_head != nullptr) dequeue(func);
while (_head != nullptr) dequeue(fn);
}
};

View File

@ -122,8 +122,7 @@ class Genode::List_model : Noncopyable
/**
* Call functor 'fn' for each const element
*/
template <typename FN>
void for_each(FN const &fn) const
void for_each(auto const &fn) const
{
for (Element const *e = _elements.first(); e; e = e->next())
fn(static_cast<ELEM const &>(*e));
@ -132,8 +131,7 @@ class Genode::List_model : Noncopyable
/**
* Call functor 'fn' for each non-const element
*/
template <typename FN>
void for_each(FN const &fn)
void for_each(auto const &fn)
{
Element *next = nullptr;
for (Element *e = _elements.first(); e; e = next) {
@ -150,8 +148,7 @@ class Genode::List_model : Noncopyable
* list-model elements are visited via recursive function calls
* instead of a 'for_each' loop.
*/
template <typename FN>
void with_first(FN const &fn) const
void with_first(auto const &fn) const
{
if (Element const *e = _elements.first())
fn(static_cast<ELEM const &>(*e));

View File

@ -18,8 +18,8 @@
namespace Genode {
template <size_t, typename FUNC>
static inline void print_lines(char const *, size_t, FUNC const &);
template <size_t>
static inline void print_lines(char const *, size_t, auto const &);
}
@ -30,7 +30,7 @@ namespace Genode {
* on the stack
* \param string character buffer, not necessarily null-terminated
* \param len number of characters to print
* \param func functor called for each line with 'char const *' as
* \param fn functor called for each line with 'char const *' as
* argument
*
* In situations where a string is supplied by an untrusted client, we cannot
@ -42,8 +42,8 @@ namespace Genode {
* The output stops when reaching the end of the buffer or when a null
* character is encountered.
*/
template <Genode::size_t MAX_LINE_LEN, typename FUNC>
void Genode::print_lines(char const *string, size_t len, FUNC const &func)
template <Genode::size_t MAX_LINE_LEN>
void Genode::print_lines(char const *string, size_t len, auto const &fn)
{
/* skip leading line breaks */
for (; *string == '\n'; string++);
@ -89,7 +89,7 @@ void Genode::print_lines(char const *string, size_t len, FUNC const &func)
copy_cstring(line_buf, string, line_len - skip_char + 1);
/* process null-terminated string in buffer */
func(line_buf);
fn(line_buf);
/* move forward to the next sub-string to process */
string += line_len;

View File

@ -52,7 +52,7 @@ Genode::Reconstructible : Noncopyable
*/
bool _constructed = false;
template <typename... ARGS> void _do_construct(ARGS &&... args)
void _do_construct(auto &&... args)
{
construct_at<MT>(_space, args...);
_constructed = true;
@ -91,11 +91,7 @@ Genode::Reconstructible : Noncopyable
* The arguments are forwarded to the constructor of the embedded
* object.
*/
template <typename... ARGS>
Reconstructible(ARGS &&... args)
{
_do_construct(args...);
}
Reconstructible(auto &&... args) { _do_construct(args...); }
~Reconstructible() { destruct(); }
@ -105,8 +101,7 @@ Genode::Reconstructible : Noncopyable
* If the 'Reconstructible' already hosts a constructed object, the old
* object will be destructed first.
*/
template <typename... ARGS>
void construct(ARGS &&... args)
void construct(auto &&... args)
{
destruct();
_do_construct(args...);
@ -134,8 +129,7 @@ Genode::Reconstructible : Noncopyable
/**
* Construct or destruct volatile object according to 'condition'
*/
template <typename... ARGS>
void conditional(bool condition, ARGS &&... args)
void conditional(bool condition, auto &&... args)
{
if (condition && !constructed())
construct(args...);

View File

@ -17,9 +17,9 @@
namespace Genode {
template <typename EXC, typename FUNC, typename HANDLER>
auto retry(FUNC func, HANDLER handler,
unsigned attempts = ~0U) -> decltype(func());
template <typename EXC>
auto retry(auto const &fn, auto const &,
unsigned attempts = ~0U) -> decltype(fn());
}
/**
@ -29,20 +29,20 @@ namespace Genode {
* is called and the function call is retried.
*
* \param EXC exception type to handle
* \param func functor to execute
* \param handler exception handler executed if 'func' raised an exception
* \param fn functor to execute
* \param exc_fn exception handler executed if 'fn' raised an exception
* of type 'EXC'
* \param attempts number of attempts to execute 'func' before giving up
* and reflecting the exception 'EXC' to the caller. If not
* specified, attempt infinitely.
*/
template <typename EXC, typename FUNC, typename HANDLER>
auto Genode::retry(FUNC func, HANDLER handler,
unsigned attempts) -> decltype(func())
template <typename EXC>
auto Genode::retry(auto const &fn, auto const &exc_fn,
unsigned attempts) -> decltype(fn())
{
for (unsigned i = 0; attempts == ~0U || i < attempts; i++)
try { return func(); }
catch (EXC) { handler(); }
try { return fn(); }
catch (EXC) { exc_fn(); }
throw EXC();
}

View File

@ -771,12 +771,12 @@ class Genode::String
* may fit perfectly into the buffer or may have been truncated.
* In general, it would be safe to assume the latter.
*/
template <typename T, typename... TAIL>
String(T const &arg, TAIL &&... args)
template <typename T>
String(T const &head, auto &&... tail)
{
/* initialize string content */
Local_output output(_buf);
Genode::print(output, arg, args...);
Genode::print(output, head, tail...);
/* add terminating null */
_buf[output.num_chars()] = 0;

View File

@ -296,23 +296,20 @@ class Genode::Xml_generator
public:
template <typename FUNC>
Xml_generator(char *dst, size_t dst_len,
char const *name, FUNC const &func)
Xml_generator(char *dst, size_t dst_len, char const *name, auto const &fn)
:
_out_buffer(dst, dst_len)
{
if (dst) {
node(name, func);
node(name, fn);
_out_buffer.append('\n');
_out_buffer.append('\0');
}
}
template <typename FUNC>
void node(char const *name, FUNC const &func = [] () { } )
void node(char const *name, auto const &fn = [] () { } )
{
Node(*this, name, func);
Node(*this, name, fn);
}
void node(char const *name) { Node(*this, name, [] () { }); }
@ -394,8 +391,7 @@ class Genode::Xml_generator
*
* This method must not be followed by calls of 'attribute'.
*/
template <typename... ARGS>
void append_content(ARGS &&... args)
void append_content(auto &&... args)
{
struct Node_output : Genode::Output
{

View File

@ -156,8 +156,7 @@ class Genode::Xml_attribute
* Note that the content of the buffer is not null-terminated but
* delimited by the size argument.
*/
template <typename FN>
void with_raw_value(FN const &fn) const
void with_raw_value(auto const &fn) const
{
/*
* Skip leading quote of the '_value' to access the actual value.
@ -173,8 +172,7 @@ class Genode::Xml_attribute
* false if attribute is invalid or value
* conversion failed
*/
template <typename T>
bool value(T &out) const
bool value(auto &out) const
{
bool result = false;
@ -678,8 +676,7 @@ class Genode::Xml_node
/**
* Call functor 'fn' with the node data '(char const *, size_t)'
*/
template <typename FN>
void with_raw_node(FN const &fn) const
void with_raw_node(auto const &fn) const
{
char const *start_ptr = _tags.start.token().start();
fn(start_ptr, _tags.end.next_token().start() - start_ptr);
@ -693,8 +690,7 @@ class Genode::Xml_node
*
* If the node has no content, the functor 'fn' is not called.
*/
template <typename FN>
void with_raw_content(FN const &fn) const
void with_raw_content(auto const &fn) const
{
if (_tags.start.type() == Tag::EMPTY)
return;
@ -844,8 +840,7 @@ class Genode::Xml_node
* The functor is called with the sub node as argument.
* If no matching sub node exists, the functor is not called.
*/
template <typename FN>
void with_optional_sub_node(char const *type, FN const &fn) const
void with_optional_sub_node(char const *type, auto const &fn) const
{
if (has_sub_node(type))
fn(sub_node(type));
@ -855,22 +850,20 @@ class Genode::Xml_node
* Apply functor 'fn' to first sub node of specified type
*
* The functor is called with the sub node as argument.
* If no matching sub node exists, the functor 'fn_nexists' is called.
* If no matching sub node exists, the functor 'missing_fn' is called.
*/
template <typename FN, typename FN_NEXISTS>
void with_sub_node(char const *type, FN const &fn, FN_NEXISTS const &fn_nexists) const
void with_sub_node(char const *type, auto const &fn, auto const &missing_fn) const
{
if (has_sub_node(type))
fn(sub_node(type));
else
fn_nexists();
missing_fn();
}
/**
* Execute functor 'fn' for each sub node of specified type
*/
template <typename FN>
void for_each_sub_node(char const *type, FN const &fn) const
void for_each_sub_node(char const *type, auto const &fn) const
{
if (!has_sub_node(type))
return;
@ -887,8 +880,7 @@ class Genode::Xml_node
/**
* Execute functor 'fn' for each sub node
*/
template <typename FN>
void for_each_sub_node(FN const &fn) const
void for_each_sub_node(auto const &fn) const
{
for_each_sub_node(nullptr, fn);
}
@ -993,8 +985,7 @@ class Genode::Xml_node
/**
* Execute functor 'fn' for each attribute
*/
template <typename FN>
void for_each_attribute(FN const &fn) const
void for_each_attribute(auto const &fn) const
{
if (!_tags.start.has_attribute())
return;

View File

@ -105,13 +105,12 @@ struct Genode::Vm_connection : Connection<Vm_session>, Rpc_client<Vm_session>
Rpc_client<Vm_session>(cap())
{ }
template <typename FUNC>
auto with_upgrade(FUNC func) -> decltype(func())
auto with_upgrade(auto const &fn) -> decltype(fn())
{
return Genode::retry<Genode::Out_of_ram>(
[&] () {
return Genode::retry<Genode::Out_of_caps>(
[&] () { return func(); },
[&] () { return fn(); },
[&] () { this->upgrade_caps(2); });
},
[&] () { this->upgrade_ram(4096); }