Skip to content

Commit 69b0943

Browse files
authored
Scoped Storage and static Storage class (#205)
1 parent f51e232 commit 69b0943

File tree

9 files changed

+162
-78
lines changed

9 files changed

+162
-78
lines changed

bootstrap/include/bootstrap/build_buildcc.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ class BuildBuildCC {
7777
const BaseToolchain &toolchain_;
7878
TargetEnv env_;
7979

80-
PersistentStorage storage_;
80+
ScopedStorage storage_;
8181
};
8282

8383
} // namespace buildcc

buildcc/buildcc.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "env/host_compiler.h"
2828
#include "env/util.h"
2929
#include "env/command.h"
30+
#include "env/storage.h"
3031

3132
// Base
3233
#include "toolchain/toolchain.h"
@@ -57,6 +58,5 @@
5758
// BuildCC Modules
5859
#include "args/args.h"
5960
#include "args/register.h"
60-
#include "args/persistent_storage.h"
6161

6262
#endif

buildcc/lib/args/CMakeLists.txt

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -41,20 +41,12 @@ target_link_libraries(test_register PRIVATE
4141
mock_args
4242
)
4343

44-
add_executable(test_persistent_storage
45-
test/test_persistent_storage.cpp
46-
)
47-
target_link_libraries(test_persistent_storage PRIVATE mock_args)
48-
4944
add_test(NAME test_args COMMAND test_args
5045
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/test
5146
)
5247
add_test(NAME test_register COMMAND test_register
5348
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/test
5449
)
55-
add_test(NAME test_persistent_storage COMMAND test_persistent_storage
56-
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/test
57-
)
5850
endif()
5951

6052
set(ARGS_SRCS
@@ -64,7 +56,6 @@ set(ARGS_SRCS
6456
src/tasks.cpp
6557
include/args/args.h
6658
include/args/register.h
67-
include/args/persistent_storage.h
6859
)
6960

7061
if(${BUILDCC_BUILD_AS_SINGLE_LIB})

buildcc/lib/args/test/test_persistent_storage.cpp

Lines changed: 0 additions & 60 deletions
This file was deleted.

buildcc/lib/env/CMakeLists.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ if (${TESTING})
66

77
src/env.cpp
88
src/task_state.cpp
9+
src/storage.cpp
910

1011
src/command.cpp
1112
mock/execute.cpp
@@ -38,10 +39,14 @@ if (${TESTING})
3839
add_executable(test_command test/test_command.cpp)
3940
target_link_libraries(test_command PRIVATE mock_env)
4041

42+
add_executable(test_storage test/test_storage.cpp)
43+
target_link_libraries(test_storage PRIVATE mock_env)
44+
4145
add_test(NAME test_static_project COMMAND test_static_project)
4246
add_test(NAME test_env_util COMMAND test_env_util)
4347
add_test(NAME test_task_state COMMAND test_task_state)
4448
add_test(NAME test_command COMMAND test_command)
49+
add_test(NAME test_storage COMMAND test_storage)
4550
endif()
4651

4752
set(ENV_SRCS
@@ -64,6 +69,9 @@ set(ENV_SRCS
6469
src/command.cpp
6570
src/execute.cpp
6671
include/env/command.h
72+
73+
src/storage.cpp
74+
include/env/storage.h
6775
)
6876

6977
if(${BUILDCC_BUILD_AS_SINGLE_LIB})

buildcc/lib/args/include/args/persistent_storage.h renamed to buildcc/lib/env/include/env/storage.h

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,11 @@
1414
* limitations under the License.
1515
*/
1616

17-
#ifndef ARGS_PERSISTENT_STORAGE_H_
18-
#define ARGS_PERSISTENT_STORAGE_H_
17+
#ifndef ENV_STORAGE_H_
18+
#define ENV_STORAGE_H_
1919

2020
#include <functional>
21+
#include <memory>
2122
#include <string>
2223
#include <typeinfo>
2324
#include <unordered_map>
@@ -28,17 +29,19 @@
2829

2930
namespace buildcc {
3031

31-
class PersistentStorage {
32+
class ScopedStorage {
3233
public:
33-
PersistentStorage() {}
34-
~PersistentStorage() {
34+
ScopedStorage() {}
35+
~ScopedStorage() {
3536
for (const auto &ptr_iter : ptrs_) {
3637
ptr_iter.second.destructor();
3738
}
3839
ptrs_.clear();
3940
env::assert_fatal(ptrs_.empty(), "Memory not deallocated");
4041
}
4142

43+
ScopedStorage(const ScopedStorage &) = delete;
44+
4245
template <typename T, typename... Params>
4346
T &Add(const std::string &identifier, Params &&...params) {
4447
T *ptr = new T(std::forward<Params>(params)...);
@@ -69,7 +72,7 @@ class PersistentStorage {
6972
// https://stackoverflow.com/questions/123758/how-do-i-remove-code-duplication-between-similar-const-and-non-const-member-func/123995
7073
template <typename T> T &Ref(const std::string &identifier) {
7174
return const_cast<T &>(
72-
static_cast<const PersistentStorage &>(*this).ConstRef<T>(identifier));
75+
static_cast<const ScopedStorage &>(*this).ConstRef<T>(identifier));
7376
}
7477

7578
private:
@@ -90,6 +93,34 @@ class PersistentStorage {
9093
std::unordered_map<std::string, PtrMetadata> ptrs_;
9194
};
9295

96+
class Storage {
97+
public:
98+
Storage() = delete;
99+
Storage(const Storage &) = delete;
100+
Storage(Storage &&) = delete;
101+
102+
static void Init() { internal_ = std::make_unique<ScopedStorage>(); }
103+
static void Deinit() { internal_.reset(nullptr); }
104+
105+
template <typename T, typename... Params>
106+
static T &Add(const std::string &identifier, Params &&...params) {
107+
return internal_->Add<T, Params...>(identifier,
108+
std::forward<Params>(params)...);
109+
}
110+
111+
template <typename T>
112+
static const T &ConstRef(const std::string &identifier) {
113+
return internal_->ConstRef<T>(identifier);
114+
}
115+
116+
template <typename T> static T &Ref(const std::string &identifier) {
117+
return internal_->Ref<T>(identifier);
118+
}
119+
120+
private:
121+
static std::unique_ptr<ScopedStorage> internal_;
122+
};
123+
93124
} // namespace buildcc
94125

95126
#endif

buildcc/lib/env/src/storage.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/*
2+
* Copyright 2021-2022 Niket Naidu. All rights reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#include "env/storage.h"
18+
19+
namespace buildcc {
20+
21+
std::unique_ptr<ScopedStorage> Storage::internal_;
22+
23+
}

buildcc/lib/env/test/test_storage.cpp

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
#include "env/storage.h"
2+
3+
// NOTE, Make sure all these includes are AFTER the system and header includes
4+
#include "CppUTest/CommandLineTestRunner.h"
5+
#include "CppUTest/MemoryLeakDetectorNewMacros.h"
6+
#include "CppUTest/TestHarness.h"
7+
#include "CppUTest/Utest.h"
8+
#include "CppUTestExt/MockSupport.h"
9+
10+
// clang-format off
11+
TEST_GROUP(ScopedStorageTestGroup)
12+
{
13+
};
14+
15+
TEST_GROUP(StorageTestGroup)
16+
{
17+
void setup() {
18+
buildcc::Storage::Init();
19+
}
20+
void teardown() {
21+
buildcc::Storage::Deinit();
22+
}
23+
};
24+
// clang-format on
25+
26+
class BigObj {};
27+
28+
class BigObjWithParameters {
29+
public:
30+
BigObjWithParameters(const std::string &name, int id, const BigObj &obj)
31+
: name_(name) {
32+
(void)id;
33+
(void)obj;
34+
}
35+
36+
const std::string &GetName() const { return name_; }
37+
38+
private:
39+
std::string name_;
40+
};
41+
42+
static BigObj obj;
43+
44+
TEST(ScopedStorageTestGroup, BasicUsage) {
45+
buildcc::ScopedStorage storage;
46+
storage.Add<BigObjWithParameters>("identifier", "name", 10, obj);
47+
storage.Add<BigObjWithParameters>("identifier2", "name2", 12, obj);
48+
49+
// Usage
50+
storage.ConstRef<BigObjWithParameters>("identifier").GetName();
51+
storage.Ref<BigObjWithParameters>("identifier2").GetName();
52+
53+
// Automatic cleanup here
54+
}
55+
56+
TEST(ScopedStorageTestGroup, IncorrectUsage) {
57+
buildcc::ScopedStorage storage;
58+
storage.Add<BigObjWithParameters>("identifier", "name", 10, obj);
59+
60+
// We try to cast to a different type!
61+
CHECK_THROWS(std::exception, storage.Ref<BigObj>("identifier"));
62+
63+
// We use a wrong identifier
64+
CHECK_THROWS(std::exception,
65+
storage.Ref<BigObjWithParameters>("identifier2"));
66+
}
67+
68+
std::string &toReference(std::string *pointer) { return *pointer; }
69+
70+
TEST(ScopedStorageTestGroup, NullptrDelete) {
71+
buildcc::ScopedStorage storage;
72+
storage.Remove<std::string>(nullptr);
73+
}
74+
75+
TEST(StorageTestGroup, BasicUsage) {
76+
buildcc::Storage::Add<BigObjWithParameters>("identifier", "name", 10, obj);
77+
buildcc::Storage::Add<BigObjWithParameters>("identifier2", "name2", 12, obj);
78+
79+
// Usage
80+
const auto &bigobj =
81+
buildcc::Storage::ConstRef<BigObjWithParameters>("identifier").GetName();
82+
const auto &bigobj2 =
83+
buildcc::Storage::Ref<BigObjWithParameters>("identifier2").GetName();
84+
85+
STRCMP_EQUAL(bigobj.c_str(), "name");
86+
STRCMP_EQUAL(bigobj2.c_str(), "name2");
87+
}
88+
89+
int main(int ac, char **av) {
90+
return CommandLineTestRunner::RunAllTests(ac, av);
91+
}

buildexe/include/buildexe/build_env_setup.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ class BuildEnvSetup {
6666
const BuildExeArgs &buildexe_args_;
6767

6868
ArgToolchainState state_;
69-
PersistentStorage storage_;
69+
ScopedStorage storage_;
7070
};
7171

7272
} // namespace buildcc

0 commit comments

Comments
 (0)