Skip to content

Commit acee382

Browse files
authored
Add Cxx Util module (#149)
1 parent 34a60c8 commit acee382

File tree

6 files changed

+476
-1
lines changed

6 files changed

+476
-1
lines changed

.github/copilot-instructions.md

Lines changed: 216 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,216 @@
1+
# OpenGraph Copilot Instructions
2+
3+
This file contains coding guidelines and conventions for AI assistants working on the OpenGraph project.
4+
5+
## Quick Reference
6+
7+
### Key Principles
8+
- Use `swift-testing` framework with `#expect` macro (not XCTest)
9+
- Follow OpenGraph C++ and Swift interop patterns
10+
- Trim trailing whitespaces automatically
11+
- Use 4-space indentation consistently
12+
13+
## Testing Guidelines
14+
15+
### Testing Framework
16+
17+
- Use the `swift-testing` framework with the `#expect` macro for all test assertions
18+
- Import testing framework with: `import Testing`
19+
- Do NOT use XCTest framework unless specifically required for compatibility
20+
21+
### Test Structure
22+
23+
```swift
24+
import Testing
25+
26+
struct OpenGraphTests {
27+
@Test
28+
func functionality() {
29+
let value = SomeType()
30+
31+
#expect(value.property == expectedValue)
32+
#expect(value.method() == expectedResult)
33+
}
34+
35+
@Test
36+
func errorConditions() {
37+
#expect(throws: SomeError.self) {
38+
try riskyOperation()
39+
}
40+
}
41+
}
42+
```
43+
44+
### Test Conventions
45+
46+
- **Do NOT write any comments in test case body** - keep test code clean and self-explanatory
47+
- Use descriptive test function names that clearly indicate what is being tested
48+
- Group related tests using `// MARK: -` sections
49+
- Use `#expect` for all assertions instead of XCTest assertions
50+
- Prefer multiple focused tests over one large test
51+
- Do not add test prefix to test function names (e.g., `testFunctionality` should be `functionality`)
52+
- Use `@Test` attribute for test functions
53+
54+
## Code Organization
55+
56+
### File Structure
57+
- Use `// MARK: -` to separate different topics and sections within files
58+
- Organize code logically with clear separation of concerns
59+
- Place imports at the top, followed by type definitions, then implementations
60+
61+
### Example MARK Usage
62+
```swift
63+
// MARK: - A
64+
65+
...
66+
67+
// MARK: - B
68+
69+
...
70+
71+
// MARK: - C
72+
73+
...
74+
```
75+
76+
## Swift Coding Style
77+
78+
### Access Control Hierarchy
79+
80+
1. `public` - External API surface
81+
2. `internal` - Module-internal APIs (default and should be omitted if not needed)
82+
3. `private` - Implementation details
83+
84+
### Naming Conventions
85+
86+
- Follow Swift API Design Guidelines
87+
- Use descriptive names that clearly indicate purpose
88+
- Prefer full words over abbreviations
89+
- Use camelCase for variables, functions, and properties
90+
- Use PascalCase for types, protocols, and cases
91+
92+
### Code Formatting Rules
93+
94+
- **Automatically trim trailing whitespaces including whitespace-only lines**
95+
- Use consistent indentation (4 spaces, not tabs)
96+
- Place opening braces on the same line as the declaration
97+
- Use proper spacing around operators and after commas
98+
- Align code vertically when it improves readability
99+
- Maximum line length: 120 characters (soft limit)
100+
101+
## C++ Coding Style
102+
103+
### OpenGraphCxx Guidelines
104+
105+
- Follow existing OpenGraph C++ patterns and conventions
106+
- Use `OG_INLINE` and `OG_CONSTEXPR` macros for inline and constexpr functions
107+
- Use `OG_NOEXCEPT` for exception specifications
108+
- Maintain compatibility with existing OpenGraph APIs
109+
- Use proper header guards with project-specific naming
110+
111+
### Memory Management
112+
113+
- Use RAII principles for resource management
114+
- Prefer smart pointers and custom deleters for automatic cleanup
115+
- Use `ptr<T>` template for OpenGraph-specific pointer management
116+
- Implement proper validation and assertion mechanisms
117+
118+
### Template Usage
119+
120+
```cpp
121+
template <typename T>
122+
class ptr {
123+
// Implementation following OpenGraph patterns
124+
};
125+
```
126+
127+
## Architecture Patterns
128+
129+
### OpenGraph Compatibility
130+
- Maintain API compatibility with existing OpenGraph functionality
131+
- Use similar naming conventions and parameter patterns
132+
- Implement protocols and extensions that mirror OpenGraph's design
133+
134+
### Module Organization
135+
- Keep related functionality in appropriate modules
136+
- Use clear module boundaries between OpenGraphCxx and Swift layers
137+
- Avoid circular dependencies between modules
138+
139+
### C++/Swift Interop
140+
- Use proper bridging headers for C++ integration
141+
- Ensure memory safety across language boundaries
142+
- Handle exceptions and errors appropriately at boundaries
143+
144+
## Documentation
145+
146+
### Code Comments
147+
- Write clear, concise comments for complex logic
148+
- Use documentation comments (`///`) for APIs documentation
149+
- Avoid obvious comments that don't add value
150+
- Keep comments up-to-date with code changes
151+
152+
### API Documentation
153+
```swift
154+
/// A brief description of what this function does.
155+
///
156+
/// - Parameter value: Description of the parameter
157+
/// - Returns: Description of the return value
158+
/// - Throws: Description of potential errors
159+
func someFunction(value: String) throws -> Int {
160+
// Implementation
161+
}
162+
```
163+
164+
## Performance Considerations
165+
166+
- Optimize memory allocation patterns using OpenGraph's table/page system
167+
- Use lazy initialization for expensive computations
168+
- Consider memory management and avoid retain cycles
169+
- Optimize for common use cases while maintaining flexibility
170+
- Profile memory usage patterns in graph operations
171+
172+
## Dependencies and Imports
173+
174+
### Swift Files
175+
- Minimize external dependencies
176+
- Use conditional compilation for platform-specific code
177+
- Import only what is needed
178+
- Organize imports alphabetically within groups
179+
180+
### C++ Files
181+
- Use proper header inclusion guards
182+
- Include OpenGraph base headers first
183+
- Follow dependency order in include statements
184+
- Use forward declarations when possible
185+
186+
## Platform Compatibility
187+
188+
- Support multiple Apple platforms (iOS, macOS, watchOS, tvOS, visionOS)
189+
- Use availability annotations when using platform-specific APIs
190+
- Test on supported platform versions
191+
- Use feature detection rather than version checking when possible
192+
- Handle platform differences in C++ code using preprocessor directives
193+
194+
## Memory and Data Management
195+
196+
### OpenGraph Patterns
197+
- Use `data::table` for memory region management
198+
- Implement proper page allocation and deallocation
199+
- Use `ptr<T>` for type-safe offset-based pointers
200+
- Follow OpenGraph's zone-based memory organization
201+
202+
### Validation and Assertions
203+
- Use `assert_valid` methods for pointer validation
204+
- Implement proper precondition checking
205+
- Use OpenGraph's assertion macros consistently
206+
- Handle edge cases gracefully
207+
208+
---
209+
210+
## Troubleshooting
211+
212+
### Common Issues
213+
- **Build errors**: Check C++/Swift bridging and header paths
214+
- **Test failures**: Ensure using `#expect` not XCTest assertions
215+
- **Memory issues**: Verify proper pointer validation and table usage
216+
- **Interop problems**: Check Swift/C++ type compatibility

Sources/OpenGraphCxx/include/OpenGraphCxx/Data/zone.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ class zone {
4343
return info(zone_id(), deleted);
4444
}
4545
private:
46-
enum {
46+
enum : uint32_t {
4747
zone_id_mask = 0x7fffffff,
4848
deleted = 0x80000000,
4949
};
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
//
2+
// cf_ptr.hpp
3+
// OpenGraphCxx
4+
//
5+
// Status: Complete
6+
// Modified based Compute code
7+
8+
#ifndef OPENGRAPH_CXX_UTIL_CF_PTR_HPP
9+
#define OPENGRAPH_CXX_UTIL_CF_PTR_HPP
10+
11+
#include <OpenGraph/OGBase.h>
12+
#include <CoreFoundation/CoreFoundation.h>
13+
14+
OG_ASSUME_NONNULL_BEGIN
15+
16+
namespace util {
17+
18+
template <typename T> class cf_ptr {
19+
private:
20+
CFTypeRef _storage;
21+
22+
static OG_INLINE CFTypeRef to_storage(T ref) { return (CFTypeRef)(ref); }
23+
static OG_INLINE T from_storage(CFTypeRef storage) { return (T)storage; }
24+
25+
public:
26+
OG_CONSTEXPR cf_ptr() OG_NOEXCEPT : _storage(nullptr) {}
27+
OG_CONSTEXPR cf_ptr(std::nullptr_t) OG_NOEXCEPT : _storage(nullptr) {}
28+
29+
explicit cf_ptr(T ref) : _storage(to_storage(ref)) {
30+
if (_storage) {
31+
CFRetain(_storage);
32+
}
33+
}
34+
35+
~cf_ptr() {
36+
if (_storage) {
37+
CFRelease(_storage);
38+
}
39+
}
40+
41+
// Copy and move constructors
42+
43+
cf_ptr(const cf_ptr &other) OG_NOEXCEPT : _storage(other._storage) {
44+
if (_storage) {
45+
CFRetain(_storage);
46+
}
47+
};
48+
49+
cf_ptr(cf_ptr &&other) OG_NOEXCEPT : _storage(std::exchange(other._storage, nullptr)) {};
50+
51+
// Copy and move assignment operators
52+
53+
cf_ptr &operator=(const cf_ptr &other) OG_NOEXCEPT {
54+
if (this != &other) {
55+
if (_storage) {
56+
CFRelease(_storage);
57+
}
58+
_storage = other._storage;
59+
if (_storage) {
60+
CFRetain(_storage);
61+
}
62+
}
63+
return *this;
64+
};
65+
66+
cf_ptr &operator=(cf_ptr &&other) OG_NOEXCEPT {
67+
if (this != &other) {
68+
if (_storage) {
69+
CFRelease(_storage);
70+
}
71+
_storage = other._storage;
72+
other._storage = nullptr;
73+
}
74+
return *this;
75+
}
76+
77+
// Modifiers
78+
79+
void reset() OG_NOEXCEPT { reset(nullptr); }
80+
81+
void reset(T ref = nullptr) OG_NOEXCEPT {
82+
if (_storage != ref) {
83+
if (_storage) {
84+
CFRelease(_storage);
85+
}
86+
_storage = to_storage(ref);
87+
if (_storage) {
88+
CFRetain(_storage);
89+
}
90+
}
91+
}
92+
93+
// Observers
94+
95+
T get() const OG_NOEXCEPT { return from_storage(_storage); };
96+
97+
explicit operator bool() const OG_NOEXCEPT { return _storage != nullptr; }
98+
}; /* class cf_ptr */
99+
100+
using cf_data_ptr = cf_ptr<CFDataRef>;
101+
using cf_mutable_data_ptr = cf_ptr<CFMutableDataRef>;
102+
103+
} /* namespace util */
104+
105+
OG_ASSUME_NONNULL_END
106+
107+
#endif /* OPENGRAPH_CXX_UTIL_CF_PTR_HPP */
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
//
2+
// free_deleter.hpp
3+
// OpenGraphCxx
4+
//
5+
// Status: Complete
6+
// Modified based Compute code
7+
8+
#ifndef OPENGRAPH_CXX_UTIL_FREE_DELETER_HPP
9+
#define OPENGRAPH_CXX_UTIL_FREE_DELETER_HPP
10+
11+
#include <OpenGraph/OGBase.h>
12+
13+
OG_ASSUME_NONNULL_BEGIN
14+
15+
namespace util {
16+
17+
class free_deleter {
18+
public:
19+
template <typename T> void operator()(T *_Nullable ptr) {
20+
if (ptr) {
21+
free((void *)ptr);
22+
}
23+
}
24+
}; /* class free_deleter */
25+
26+
} /* namespace util */
27+
28+
OG_ASSUME_NONNULL_END
29+
30+
#endif /* OPENGRAPH_CXX_UTIL_FREE_DELETER_HPP */

0 commit comments

Comments
 (0)