blob: e54cf2be5fdba2f170146db618c982e5b508d276 [file] [log] [blame]
Austin Schuh1d1e6ea2020-12-23 21:56:30 -08001// Copyright 2017 The Abseil Authors.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14//
15// -----------------------------------------------------------------------------
16// File: memory.h
17// -----------------------------------------------------------------------------
18//
19// This header file contains utility functions for managing the creation and
20// conversion of smart pointers. This file is an extension to the C++
21// standard <memory> library header file.
22
23#ifndef CERES_PUBLIC_INTERNAL_MEMORY_H_
24#define CERES_PUBLIC_INTERNAL_MEMORY_H_
25
26#include <memory>
27
28#ifdef CERES_HAVE_EXCEPTIONS
29#define CERES_INTERNAL_TRY try
30#define CERES_INTERNAL_CATCH_ANY catch (...)
31#define CERES_INTERNAL_RETHROW \
32 do { \
33 throw; \
34 } while (false)
35#else // CERES_HAVE_EXCEPTIONS
36#define CERES_INTERNAL_TRY if (true)
37#define CERES_INTERNAL_CATCH_ANY else if (false)
38#define CERES_INTERNAL_RETHROW \
39 do { \
40 } while (false)
41#endif // CERES_HAVE_EXCEPTIONS
42
Austin Schuh3de38b02024-06-25 18:25:10 -070043namespace ceres::internal {
Austin Schuh1d1e6ea2020-12-23 21:56:30 -080044
45template <typename Allocator, typename Iterator, typename... Args>
46void ConstructRange(Allocator& alloc,
47 Iterator first,
48 Iterator last,
49 const Args&... args) {
50 for (Iterator cur = first; cur != last; ++cur) {
51 CERES_INTERNAL_TRY {
52 std::allocator_traits<Allocator>::construct(
53 alloc, std::addressof(*cur), args...);
54 }
55 CERES_INTERNAL_CATCH_ANY {
56 while (cur != first) {
57 --cur;
58 std::allocator_traits<Allocator>::destroy(alloc, std::addressof(*cur));
59 }
60 CERES_INTERNAL_RETHROW;
61 }
62 }
63}
64
65template <typename Allocator, typename Iterator, typename InputIterator>
66void CopyRange(Allocator& alloc,
67 Iterator destination,
68 InputIterator first,
69 InputIterator last) {
70 for (Iterator cur = destination; first != last;
71 static_cast<void>(++cur), static_cast<void>(++first)) {
72 CERES_INTERNAL_TRY {
73 std::allocator_traits<Allocator>::construct(
74 alloc, std::addressof(*cur), *first);
75 }
76 CERES_INTERNAL_CATCH_ANY {
77 while (cur != destination) {
78 --cur;
79 std::allocator_traits<Allocator>::destroy(alloc, std::addressof(*cur));
80 }
81 CERES_INTERNAL_RETHROW;
82 }
83 }
84}
85
Austin Schuh3de38b02024-06-25 18:25:10 -070086} // namespace ceres::internal
Austin Schuh1d1e6ea2020-12-23 21:56:30 -080087
88#endif // CERES_PUBLIC_INTERNAL_MEMORY_H_