blob: ec565fd8ef9ebb8c8e2e20a36eb7acc4d471b8ce [file] [log] [blame]
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you 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.
#ifndef CELIX_CELIX_CLEANUP_H
#define CELIX_CELIX_CLEANUP_H
#ifdef __cplusplus
extern "C" {
#endif
#include "celix_compiler.h"
/* private */
#define _CELIX_AUTOPTR_FUNC_NAME(TypeName) celix_autoptr_cleanup_##TypeName
#define _CELIX_AUTOPTR_CLEAR_FUNC_NAME(TypeName) celix_autoptr_clear_##TypeName
#define _CELIX_AUTOPTR_TYPENAME(TypeName) TypeName##_autoptr
#define _CELIX_AUTO_FUNC_NAME(TypeName) celix_auto_cleanup_##TypeName
#define _CELIX_DEFINE_AUTOPTR_CLEANUP_FUNCS(TypeName, cleanup) \
typedef TypeName* _CELIX_AUTOPTR_TYPENAME(TypeName); \
static CELIX_UNUSED inline void _CELIX_AUTOPTR_CLEAR_FUNC_NAME(TypeName)(TypeName * _ptr) { \
if (_ptr) \
(cleanup)(_ptr); \
} \
static CELIX_UNUSED inline void _CELIX_AUTOPTR_FUNC_NAME(TypeName)(TypeName** _ptr) { \
_CELIX_AUTOPTR_CLEAR_FUNC_NAME(TypeName)(*_ptr); \
}
/* API */
/**
* @brief Defines the appropriate cleanup function for a pointer type.
*
* The function will not be called if the variable to be cleaned up contains NULL.
* With this definition, it will be possible to use celix_autoptr() with @a TypeName.
*
* @param TypeName A type name to define a celix_autoptr() cleanup function for.
* @param func The cleanup function.
*/
#define CELIX_DEFINE_AUTOPTR_CLEANUP_FUNC(TypeName, func) _CELIX_DEFINE_AUTOPTR_CLEANUP_FUNCS(TypeName, func)
/**
* @brief Defines the appropriate cleanup function for a type.
* With this definition, it will be possible to use celix_auto() with @a TypeName.
* @param TypeName: A type name to define a celix_auto() cleanup function for.
* @param func The clear function.
*/
#define CELIX_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(TypeName, func) \
static CELIX_UNUSED inline void _CELIX_AUTO_FUNC_NAME(TypeName)(TypeName* _ptr) { (func)(_ptr); }
/**
* @brief Defines the appropriate cleanup function for a type.
*
* With this definition, it will be possible to use celix_auto() with
* @a TypeName.
*
* This function will be rarely used. It is used with pointer-based
* typedefs and non-pointer types where the value of the variable
* represents a resource that must be freed.
*
* @a none specifies the "none" value for the type in question. It is
* probably something like NULL or `-1`. If the variable is found to
* contain this value then the free function will not be called.
*
* @param TypeName A type name to define a celix_auto() cleanup function for.
* @param func The free function.
* @param none The "none" value for the type.
*/
#define CELIX_DEFINE_AUTO_CLEANUP_FREE_FUNC(TypeName, func, none) \
static CELIX_UNUSED inline void _CELIX_AUTO_FUNC_NAME(TypeName)(TypeName* _ptr) { \
if (*_ptr != none) \
(func)(*_ptr); \
}
/**
* @brief Helper to declare a pointer variable with automatic cleanup.
*
* The variable is cleaned up in a way appropriate to its type when the
* variable goes out of scope. The type must support this.
* The way to clean up the type must have been defined using the macro
* CELIX_DEFINE_AUTOPTR_CLEANUP_FUNC().
*
* This is meant to be used to declare pointers to types with cleanup
* functions. The type of the variable is a pointer to @a TypeName. You
* must not add your own `*`.
*/
#define celix_autoptr(TypeName) CELIX_UNUSED CELIX_CLEANUP(_CELIX_AUTOPTR_FUNC_NAME(TypeName)) _CELIX_AUTOPTR_TYPENAME(TypeName)
/**
* @brief Helper to declare a variable with automatic cleanup.
*
* The variable is cleaned up in a way appropriate to its type when the
* variable goes out of scope. The type must support this.
* The way to clean up the type must have been defined using one of the macros
* CELIX_DEFINE_AUTO_CLEANUP_CLEAR_FUNC() or CELIX_DEFINE_AUTO_CLEANUP_FREE_FUNC().
*
* This is meant to be used with stack-allocated structures and
* non-pointer types. For the (more commonly used) pointer version, see
* celix_autoptr().
*/
#define celix_auto(TypeName) CELIX_UNUSED CELIX_CLEANUP(_CELIX_AUTO_FUNC_NAME(TypeName)) TypeName
/**
* @brief Transfer the ownership of the pointer from the
* referenced variable to the "caller" of the macro.
*/
#ifdef __cplusplus
#define celix_steal_ptr(p) \
({ auto __ptr = (p); (p) = NULL; __ptr; })
#else
#define celix_steal_ptr(p) \
({ __auto_type __ptr = (p); (p) = NULL; __ptr; })
#endif
#ifdef __cplusplus
}
#endif
#endif // CELIX_CELIX_CLEANUP_H