1 // Copyright (c) 2017-2026, Lawrence Livermore National Security, LLC and other CEED contributors. 2 // All Rights Reserved. See the top-level LICENSE and NOTICE files for details. 3 // 4 // SPDX-License-Identifier: BSD-2-Clause 5 // 6 // This file is part of CEED: http://github.com/ceed 7 8 #include <ceed-impl.h> 9 #include <ceed.h> 10 #include <ceed/backend.h> 11 12 /// @file 13 /// Implementation of CeedObject functionality 14 15 /// ---------------------------------------------------------------------------- 16 /// CeedObject Backend API 17 /// ---------------------------------------------------------------------------- 18 /// @addtogroup CeedBackend 19 /// @{ 20 21 /** 22 @brief Create a `CeedObject`. 23 24 Note: This interface takes a `CeedObject` and not a pointer to a `CeedObject` like other `Ceed*Create` interfaces. 25 This `CeedObject` will have already been allocated a the first part of the `Ceed*` struct. 26 This function is only intended to be called inside of `Ceed*Create` functions. 27 28 @param[in] ceed `Ceed` object to reference 29 @param[in] view_function `Ceed*` function for viewing the `obj` 30 @param[in] destroy_function `Ceed*` function for destroying the `obj` 31 @param[out] obj Address of the variable where is `CeedObject` exists 32 33 @return An error code: 0 - success, otherwise - failure 34 35 @ref Backend 36 **/ 37 int CeedObjectCreate(Ceed ceed, int (*view_function)(CeedObject, FILE *), int (*destroy_function)(CeedObject *), CeedObject obj) { 38 obj->ceed = NULL; 39 if (ceed) CeedCall(CeedReferenceCopy(ceed, &obj->ceed)); 40 obj->View = view_function; 41 CeedCheck(destroy_function, CeedObjectReturnCeed(obj), CEED_ERROR_UNSUPPORTED, "Must provide destroy function to create CeedObject"); 42 obj->Destroy = destroy_function; 43 obj->ref_count = 1; 44 return CEED_ERROR_SUCCESS; 45 } 46 47 /** 48 @brief Increment the reference counter for a `CeedObject` 49 50 @param[in,out] obj `CeedObject` to increment the reference counter 51 52 @return An error code: 0 - success, otherwise - failure 53 54 @ref Backend 55 **/ 56 int CeedObjectReference(CeedObject obj) { 57 obj->ref_count++; 58 return CEED_ERROR_SUCCESS; 59 } 60 61 /** 62 @brief Decrement the reference counter for a `CeedObject` 63 64 @param[in,out] obj `CeedObject` to decrement the reference counter 65 66 @return The new reference count 67 68 @ref Backend 69 **/ 70 int CeedObjectDereference(CeedObject obj) { 71 return --obj->ref_count; // prefix notation, to get new number of references 72 } 73 74 /** 75 @brief Destroy a @ref CeedObject 76 77 @param[in,out] obj `CeedObject` to destroy 78 79 @return An error code: 0 - success, otherwise - failure 80 81 @ref Backend 82 **/ 83 int CeedObjectDestroy_Private(CeedObject obj) { 84 CeedCheck(obj->ref_count == 0, CeedObjectReturnCeed(obj), CEED_ERROR_UNSUPPORTED, 85 "Cannot destroy CeedObject, it is still referenced by another object"); 86 if (obj->ceed) CeedCall(CeedDestroy(&obj->ceed)); 87 return CEED_ERROR_SUCCESS; 88 } 89 90 /// @} 91 92 /// ---------------------------------------------------------------------------- 93 /// CeedObject Public API 94 /// ---------------------------------------------------------------------------- 95 /// @addtogroup CeedUser 96 /// @{ 97 98 /** 99 @brief View a `CeedObject` 100 101 @param[in] obj `CeedObject` to view 102 @param[in] stream Stream to view to, e.g., `stdout` 103 104 @return An error code: 0 - success, otherwise - failure 105 106 @ref User 107 **/ 108 int CeedObjectView(CeedObject obj, FILE *stream) { 109 if (obj->View) CeedCall(obj->View(obj, stream)); 110 return CEED_ERROR_SUCCESS; 111 } 112 113 /** 114 @brief Set the number of tabs to indent for @ref CeedObjectView() output 115 116 @param[in] obj `CeedObject` to set the number of view tabs 117 @param[in] num_tabs Number of view tabs to set 118 119 @return Error code: 0 - success, otherwise - failure 120 121 @ref User 122 **/ 123 int CeedObjectSetNumViewTabs(CeedObject obj, CeedInt num_tabs) { 124 CeedCheck(num_tabs >= 0, CeedObjectReturnCeed(obj), CEED_ERROR_MINOR, "Number of view tabs must be non-negative"); 125 obj->num_view_tabs = num_tabs; 126 return CEED_ERROR_SUCCESS; 127 } 128 129 /** 130 @brief Get the number of tabs to indent for @ref CeedObjectView() output 131 132 @param[in] obj `CeedObject` to get the number of view tabs 133 @param[out] num_tabs Number of view tabs 134 135 @return Error code: 0 - success, otherwise - failure 136 137 @ref User 138 **/ 139 int CeedObjectGetNumViewTabs(CeedObject obj, CeedInt *num_tabs) { 140 *num_tabs = obj->num_view_tabs; 141 return CEED_ERROR_SUCCESS; 142 } 143 144 /** 145 @brief Get the `Ceed` associated with a `CeedObject` 146 147 @param[in] obj `CeedObject` 148 @param[out] ceed Variable to store `Ceed` 149 150 @return An error code: 0 - success, otherwise - failure 151 152 @ref Advanced 153 **/ 154 int CeedObjectGetCeed(CeedObject obj, Ceed *ceed) { 155 *ceed = NULL; 156 CeedCall(CeedReferenceCopy(CeedObjectReturnCeed(obj), ceed)); 157 return CEED_ERROR_SUCCESS; 158 } 159 160 /** 161 @brief Return the `Ceed` associated with a `CeedObject` 162 163 @param[in] obj `CeedObject` 164 165 @return `Ceed` associated with the `basis` 166 167 @ref Advanced 168 **/ 169 Ceed CeedObjectReturnCeed(CeedObject obj) { return (obj->ceed) ? obj->ceed : (Ceed)obj; } 170 171 /** 172 @brief Destroy a @ref CeedObject 173 174 @param[in,out] obj Address of `CeedObject` to destroy 175 176 @return An error code: 0 - success, otherwise - failure 177 178 @ref Backend 179 **/ 180 int CeedObjectDestroy(CeedObject *obj) { 181 CeedCall((*obj)->Destroy(obj)); 182 return CEED_ERROR_SUCCESS; 183 } 184 185 /// @} 186