Skip to content

Commit f7cd44e

Browse files
committed
first release.
0 parents  commit f7cd44e

File tree

12 files changed

+333
-0
lines changed

12 files changed

+333
-0
lines changed

CMakeLists.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
cmake_minimum_required(VERSION 3.0)
2+
3+
project(singleton-cpp)
4+
5+
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
6+
set(CMAKE_EXECUTABLE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
7+
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
8+
9+
add_subdirectory(./src)
10+
add_subdirectory(./example)

LICENSE.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) 2021 xhawk18 -at- gmail.com
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

Readme.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
## Singleton for cpp
2+
3+
Features --
4+
5+
1. Works for both dynamical library and executable.
6+
2. Multithread safe
7+
3. Lazy consturction
8+
9+
## Usage
10+
11+
1. define a class or struct, for example
12+
13+
```
14+
class MyObject {
15+
public:
16+
int a;
17+
int b;
18+
};
19+
```
20+
21+
2. use the singleton instance
22+
23+
```
24+
MyObject &obj = singleton<MyObject>();
25+
```

example/CMakeLists.txt

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
cmake_minimum_required(VERSION 3.0)
2+
3+
project(singleton-cpp-exmaple C CXX)
4+
enable_language(C CXX)
5+
6+
set(my_headers
7+
../include/singleton-cpp/singleton.h
8+
./my_dll.h
9+
./my_dll_api.h
10+
)
11+
12+
set(my_includes
13+
../include
14+
)
15+
16+
add_library(my_dll SHARED my_dll.cpp ${my_headers})
17+
target_include_directories(my_dll PRIVATE ${my_includes})
18+
target_link_libraries(my_dll singleton)
19+
20+
21+
add_executable(my_exe my_exe.cpp ${my_headers})
22+
target_include_directories(my_exe PRIVATE ${my_includes})
23+
target_link_libraries(my_exe singleton my_dll)

example/my_dll.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#include "my_dll.h"
2+
#include "singleton-cpp/singleton.h"
3+
4+
MY_DLL_API void setValue() {
5+
6+
MyObject0 &obj0 = singleton<MyObject0>();
7+
obj0.a = 3;
8+
obj0.b = 4;
9+
10+
MyObject1 &obj1 = singleton<MyObject1>();
11+
obj1.c = "test1234";
12+
}

example/my_dll.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#pragma once
2+
#ifndef INC_MY_DLL_H_
3+
#define INC_MY_DLL_H_
4+
5+
#include "my_dll_api.h"
6+
#include <string>
7+
8+
class MyObject0 {
9+
public:
10+
int a;
11+
int b;
12+
};
13+
14+
class MyObject1 {
15+
public:
16+
std::string c;
17+
};
18+
19+
20+
MY_DLL_API void setValue();
21+
22+
23+
#endif

example/my_dll_api.h

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#pragma once
2+
#ifndef INC_MY_DLL_API_H_
3+
#define INC_MY_DLL_API_H_
4+
5+
#if defined(_WIN32) || defined(__CYGWIN__)
6+
# if defined(my_dll_EXPORTS) // add by CMake
7+
# ifdef __GNUC__
8+
# define MY_DLL_API __attribute__(dllexport)
9+
# else
10+
# define MY_DLL_API __declspec(dllexport)
11+
# endif
12+
# else
13+
# ifdef __GNUC__
14+
# define MY_DLL_API __attribute__(dllimport)
15+
# else
16+
# define MY_DLL_API __declspec(dllimport)
17+
# endif
18+
# endif // my_dll_EXPORTS
19+
20+
#elif defined __GNUC__
21+
# if __GNUC__ >= 4
22+
# define MY_DLL_API __attribute__ ((visibility ("default")))
23+
# else
24+
# define MY_DLL_API
25+
# endif
26+
27+
#elif defined __clang__
28+
# define MY_DLL_API __attribute__ ((visibility ("default")))
29+
30+
#else
31+
# error "Do not know how to export classes for this platform"
32+
#endif
33+
34+
#endif

example/my_exe.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#include "my_dll.h"
2+
#include "singleton-cpp/singleton.h"
3+
4+
int main() {
5+
// set value in dll
6+
setValue();
7+
8+
// get value from exe
9+
MyObject0 &obj0 = singleton<MyObject0>();
10+
printf("%d %d\n", obj0.a, obj0.b);
11+
12+
MyObject1 &obj1 = singleton<MyObject1>();
13+
printf("%s\n", obj1.c.c_str());
14+
15+
return 0;
16+
}

include/singleton-cpp/singleton.h

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
#pragma once
2+
#ifndef INC_SINGLETON_H_
3+
#define INC_SINGLETON_H_
4+
5+
#include <mutex>
6+
#include <typeindex>
7+
#include <memory>
8+
#include "singleton_api.h"
9+
10+
// Singleton mode for cpp
11+
//
12+
// Features --
13+
// 1. Works for both dynamical library and executable.
14+
// 2. Multithread safe
15+
// 3. Lazy consturction
16+
17+
template<typename T>
18+
class Singleton;
19+
20+
// Get singleton instance
21+
template<typename T>
22+
inline T &singleton() {
23+
return Singleton<T>::getInstance();
24+
}
25+
26+
27+
struct SingleTonHolder {
28+
void *object_;
29+
std::shared_ptr<std::mutex> mutex_;
30+
};
31+
32+
SINGLETON_API std::mutex &getSingleTonMutex();
33+
SINGLETON_API SingleTonHolder *getSingleTonType(const std::type_index &typeIndex);
34+
35+
36+
template<typename T>
37+
class Singleton {
38+
public:
39+
// Get the single instance
40+
static T &getInstance() {
41+
return *getInstancePrivate();
42+
}
43+
44+
private:
45+
// Get the single instance
46+
static T *getInstancePrivate() {
47+
static T *instance = nullptr;
48+
if (instance != nullptr)
49+
return instance;
50+
51+
SingleTonHolder *singleTonHolder = nullptr;
52+
{
53+
// Locks and get the global mutex
54+
std::lock_guard<std::mutex> myLock(getSingleTonMutex());
55+
if (instance != nullptr)
56+
return instance;
57+
58+
singleTonHolder = getSingleTonType(std::type_index(typeid(T)));
59+
}
60+
61+
// Create single instance
62+
T *instanceFromHolder = createInstanceFromHolder(singleTonHolder);
63+
64+
{
65+
// Save single instance object
66+
std::lock_guard<std::mutex> myLock(getSingleTonMutex());
67+
instance = instanceFromHolder;
68+
return instance;
69+
}
70+
}
71+
72+
static T *createInstanceFromHolder(SingleTonHolder *singleTonHolder) {
73+
// Locks class T and make sure to call construction only once
74+
std::lock_guard<std::mutex> myLock(*singleTonHolder->mutex_);
75+
if (singleTonHolder->object_ == nullptr) {
76+
// construct the instance with static funciton
77+
singleTonHolder->object_ = reinterpret_cast<void *>(getStaticInstance());
78+
}
79+
return reinterpret_cast<T *>(singleTonHolder->object_);
80+
}
81+
82+
static T *getStaticInstance() {
83+
static T t;
84+
return &t;
85+
}
86+
};
87+
88+
89+
#endif
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#pragma once
2+
#ifndef INC_SINGLETON_API_H_
3+
#define INC_SINGLETON_API_H_
4+
5+
#if defined(_WIN32) || defined(__CYGWIN__)
6+
# if defined(singleton_EXPORTS) // add by CMake
7+
# ifdef __GNUC__
8+
# define SINGLETON_API __attribute__(dllexport)
9+
# else
10+
# define SINGLETON_API __declspec(dllexport)
11+
# endif
12+
# else
13+
# ifdef __GNUC__
14+
# define SINGLETON_API __attribute__(dllimport)
15+
# else
16+
# define SINGLETON_API __declspec(dllimport)
17+
# endif
18+
# endif // singleton_EXPORTS
19+
20+
#elif defined __GNUC__
21+
# if __GNUC__ >= 4
22+
# define SINGLETON_API __attribute__ ((visibility ("default")))
23+
# else
24+
# define SINGLETON_API
25+
# endif
26+
27+
#elif defined __clang__
28+
# define SINGLETON_API __attribute__ ((visibility ("default")))
29+
30+
#else
31+
# error "Do not know how to export classes for this platform"
32+
#endif
33+
34+
#endif

0 commit comments

Comments
 (0)