blob: 45c5b67c353db52a29345289470fee563c404754 [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
43namespace ceres {
44namespace internal {
45
46template <typename Allocator, typename Iterator, typename... Args>
47void ConstructRange(Allocator& alloc,
48 Iterator first,
49 Iterator last,
50 const Args&... args) {
51 for (Iterator cur = first; cur != last; ++cur) {
52 CERES_INTERNAL_TRY {
53 std::allocator_traits<Allocator>::construct(
54 alloc, std::addressof(*cur), args...);
55 }
56 CERES_INTERNAL_CATCH_ANY {
57 while (cur != first) {
58 --cur;
59 std::allocator_traits<Allocator>::destroy(alloc, std::addressof(*cur));
60 }
61 CERES_INTERNAL_RETHROW;
62 }
63 }
64}
65
66template <typename Allocator, typename Iterator, typename InputIterator>
67void CopyRange(Allocator& alloc,
68 Iterator destination,
69 InputIterator first,
70 InputIterator last) {
71 for (Iterator cur = destination; first != last;
72 static_cast<void>(++cur), static_cast<void>(++first)) {
73 CERES_INTERNAL_TRY {
74 std::allocator_traits<Allocator>::construct(
75 alloc, std::addressof(*cur), *first);
76 }
77 CERES_INTERNAL_CATCH_ANY {
78 while (cur != destination) {
79 --cur;
80 std::allocator_traits<Allocator>::destroy(alloc, std::addressof(*cur));
81 }
82 CERES_INTERNAL_RETHROW;
83 }
84 }
85}
86
87} // namespace internal
88} // namespace ceres
89
90#endif // CERES_PUBLIC_INTERNAL_MEMORY_H_