BLPAPI C++ 3.26.4
Loading...
Searching...
No Matches
blpapi_correlationid.h
Go to the documentation of this file.
1/* Copyright 2012. Bloomberg Finance L.P.
2 *
3 * Permission is hereby granted, free of charge, to any person obtaining a copy
4 * of this software and associated documentation files (the "Software"), to
5 * deal in the Software without restriction, including without limitation the
6 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7 * sell copies of the Software, and to permit persons to whom the Software is
8 * furnished to do so, subject to the following conditions: The above
9 * copyright notice and this permission notice shall be included in all copies
10 * or substantial portions of the Software.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
13 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
15 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
16 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
17 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
18 * IN THE SOFTWARE.
19 */
20
28#ifndef INCLUDED_BLPAPI_CORRELATIONID
29#define INCLUDED_BLPAPI_CORRELATIONID
30
61#include <blpapi_call.h>
62#include <blpapi_defs.h>
63#include <blpapi_exception.h>
64#include <blpapi_types.h>
65
66#ifdef __cplusplus
67extern "C" {
68#endif
69
71struct blpapi_ManagedPtr_t_;
72typedef struct blpapi_ManagedPtr_t_ blpapi_ManagedPtr_t;
73
74typedef int (*blpapi_ManagedPtr_ManagerFunction_t)(
75 blpapi_ManagedPtr_t *managedPtr,
76 const blpapi_ManagedPtr_t *srcPtr,
77 int operation);
78
79typedef union {
80 int intValue;
81 void *ptr;
82} blpapi_ManagedPtr_t_data_;
83
84struct blpapi_ManagedPtr_t_ {
85 void *pointer;
86 blpapi_ManagedPtr_t_data_ userData[4];
87 blpapi_ManagedPtr_ManagerFunction_t manager;
88};
89
90typedef struct blpapi_CorrelationId_t_ {
91 unsigned int size : 8; // fill in the size of this struct
92 unsigned int valueType : 4; // type of value held by this correlation id
93 unsigned int classId : 16; // user defined classification id
94 unsigned int internalClassId : 4; // internal classification id
95
96 union {
97 blpapi_UInt64_t intValue;
98 blpapi_ManagedPtr_t ptrValue;
99 } value;
101
103int blpapi_CorrelationId_managedPtrAddRef(
104 int *numRef, blpapi_CorrelationId_t *cid);
105
107int blpapi_CorrelationId_managedPtrRelease(
108 int *numRef, blpapi_CorrelationId_t *cid);
109
110#ifdef __cplusplus
111}
112
114
115#include <cstring>
116#include <ostream>
117#include <utility>
118
126namespace BloombergLP {
127namespace blpapi {
128
129// ===================
130// class CorrelationId
131// ===================
132
207
208 enum {
210 };
211
213
214 void copy(const blpapi_CorrelationId_t& src, bool firstCopy);
215
216 template <typename TYPE>
217 static int managerFunc(blpapi_ManagedPtr_t *managedPtr,
218 const blpapi_ManagedPtr_t *srcPtr,
219 int operation);
220
221 template <typename TYPE> static void assertSmartPtrFits();
222
223 public:
224 // Possible return values for valueType() method.
225
239
240 // The maximum value allowed for classId
241
242 enum {
245 };
246
256 explicit CorrelationId(const blpapi_CorrelationId_t& correlation);
261
262 CorrelationId(const CorrelationId& original);
268 explicit CorrelationId(long long value, int classId = 0);
275 explicit CorrelationId(void *value, int classId = 0);
282 template <typename TYPE>
283 CorrelationId(const TYPE& smartPtr, void *pointerValue, int classId = 0);
300 void swap(CorrelationId& other);
313 ValueType valueType() const;
318 unsigned short classId() const;
324 void *asPointer() const;
331 template <typename TYPE> TYPE asSmartPointer() const;
339 long long asInteger() const;
348 const blpapi_CorrelationId_t& impl() const;
350};
351
355// FREE OPERATORS
356inline bool operator==(const CorrelationId& lhs, const CorrelationId& rhs);
365inline bool operator!=(const CorrelationId& lhs, const CorrelationId& rhs);
370inline bool operator<(const CorrelationId& lhs, const CorrelationId& rhs);
381//=============================================================================
382// INLINE FUNCTION DEFINITIONS
383//=============================================================================
384
385// -------------------
386// class CorrelationId
387// -------------------
388
390{
391 std::memset(&d_impl, 0, sizeof(d_impl));
392}
393
395 const blpapi_CorrelationId_t& correlationId)
396{
397 copy(correlationId, /* firstCopy = */ true);
398}
399
401{
402 copy(original.d_impl, /* firstCopy = */ false);
403}
404
405inline CorrelationId::CorrelationId(long long intValue, int newClassId)
406{
407 std::memset(&d_impl, 0, sizeof(d_impl));
408
409 d_impl.size = static_cast<unsigned>(sizeof(d_impl));
410 d_impl.valueType = INT_VALUE;
411 d_impl.value.intValue = static_cast<blpapi_UInt64_t>(intValue);
412 d_impl.classId = static_cast<unsigned>(newClassId);
413}
414
415inline CorrelationId::CorrelationId(void *ptrValue, int newClassId)
416{
417 std::memset(&d_impl, 0, sizeof(d_impl));
418
419 d_impl.size = static_cast<unsigned>(sizeof(d_impl));
420 d_impl.valueType = POINTER_VALUE;
421 d_impl.value.ptrValue.pointer = ptrValue;
422 d_impl.classId = static_cast<unsigned>(newClassId);
423}
424
425template <typename TYPE>
427 const TYPE& smartPtr, void *ptrValue, int newClassId)
428{
429 // If you get a compiler error here, the specified smart pointer does not
430 // fit in the CorrelationId and cannot be used at this time.
431
432 assertSmartPtrFits<TYPE>();
433
434 std::memset(&d_impl, 0, sizeof(d_impl));
435
436 d_impl.size = sizeof(d_impl);
437 d_impl.valueType = POINTER_VALUE;
438 d_impl.classId = newClassId;
439
440 d_impl.value.ptrValue.pointer = ptrValue;
441 d_impl.value.ptrValue.manager = &CorrelationId::managerFunc<TYPE>;
442
443 void *arena = (void *)d_impl.value.ptrValue.userData;
444 new (arena) TYPE(smartPtr);
445}
446
448{
449 if (POINTER_VALUE == valueType()) {
450 blpapi_ManagedPtr_ManagerFunction_t& manager
451 = d_impl.value.ptrValue.manager;
452 if (manager) {
453 int numRef = 0;
454 if (d_impl.internalClassId == e_FOREIGN_OBJECT
456 blpapi_CorrelationId_managedPtrRelease)
458 blpapi_CorrelationId_managedPtrRelease)(
459 &numRef, &d_impl)
460 == 0
461 && numRef > 0) {
462 return;
463 }
464 manager(&d_impl.value.ptrValue, 0, BLPAPI_MANAGEDPTR_DESTROY);
465 }
466 }
467}
468
470{
471 using std::swap;
472
473 swap(other.d_impl, d_impl);
474}
475
477{
478 CorrelationId tmp(rhs);
479 tmp.swap(*this);
480 return *this;
481}
482
483inline blpapi_CorrelationId_t& CorrelationId::impl() { return d_impl; }
484
486{
487 return (ValueType)d_impl.valueType;
488}
489
490inline unsigned short CorrelationId::classId() const { return d_impl.classId; }
491
492inline void *CorrelationId::asPointer() const
493{
494 return d_impl.value.ptrValue.pointer;
495}
496
497template <typename TYPE> inline TYPE CorrelationId::asSmartPointer() const
498{
499 typedef int (*ManagerFuncPtr)(
500 blpapi_ManagedPtr_t *, const blpapi_ManagedPtr_t *, int);
501
502 ManagerFuncPtr managerFnPtr
503 = static_cast<ManagerFuncPtr>(&(CorrelationId::managerFunc<TYPE>));
504 if (d_impl.valueType != POINTER_VALUE
505 || (d_impl.value.ptrValue.manager != managerFnPtr)) {
506 return TYPE();
507 }
508 return *(TYPE *)d_impl.value.ptrValue.userData;
509}
510
511inline long long CorrelationId::asInteger() const
512{
513 return static_cast<long long>(d_impl.value.intValue);
514}
515
516inline const blpapi_CorrelationId_t& CorrelationId::impl() const
517{
518 return d_impl;
519}
520
521inline void CorrelationId::copy(
522 const blpapi_CorrelationId_t& src, bool firstCopy)
523{
524 d_impl = src;
525
526 if (POINTER_VALUE == valueType()) {
527 blpapi_ManagedPtr_ManagerFunction_t& manager
528 = d_impl.value.ptrValue.manager;
529 if (manager) {
530 if (d_impl.internalClassId == e_FOREIGN_OBJECT) {
531 if (firstCopy) {
532 // This CorrelationId is created from a C-handle, not from
533 // another C++ CorrelationId. But this C-handle can contain
534 // a pointer to a reference counter previously created in
535 // C++ layer. It is unsafe to reuse as it might be a
536 // dangling pointer by this time. Reset userData. This
537 // allows to create a new reference counter for new C++
538 // copies of this CorrelationId.
539 std::memset(&d_impl.value.ptrValue.userData,
540 0,
541 sizeof(d_impl.value.ptrValue.userData));
542 }
543 int numRef = 0;
545 BLPAPI_CALL(blpapi_CorrelationId_managedPtrAddRef)(
546 &numRef, &d_impl));
547 if (numRef > 1) {
548 return;
549 }
550 }
551 manager(&d_impl.value.ptrValue,
552 &src.value.ptrValue,
554 }
555 }
556}
557
558template <typename TYPE>
559inline int CorrelationId::managerFunc(blpapi_ManagedPtr_t *managedPtr,
560 const blpapi_ManagedPtr_t *srcPtr,
561 int operation)
562{
563 if (operation == BLPAPI_MANAGEDPTR_COPY) {
564 managedPtr->pointer = srcPtr->pointer;
565 managedPtr->manager = srcPtr->manager;
566
567 void *arena = managedPtr->userData;
568 new (arena) TYPE(*((TYPE *)&srcPtr->userData[0]));
569 } else if (operation == BLPAPI_MANAGEDPTR_DESTROY) {
570 TYPE *managedPtr_p = (TYPE *)&managedPtr->userData[0];
571 managedPtr_p->~TYPE();
572 } else if (operation == BLPAPI_MANAGEDPTR_IMPOSSIBLE_OPERATION) {
573 static int uniquePerTemplateInstantiation;
574
575 const int *address = &uniquePerTemplateInstantiation;
576 int rc = 0;
577 std::memcpy(&rc, &address, std::min(sizeof address, sizeof rc));
578 return rc;
579 // Instantiations of this function template, 'managerFunc<TYPE>',
580 // will never be called with 'operation' equal to
581 // 'BLPAPI_MANAGEDPTR_IMPOSSIBLE_OPERATION': this branch will never
582 // be executed.
583 //
584 // The observable use of the address of a local static variable
585 // forces '&managerFunc<T1> != &managerFunc<T2>' for types
586 // 'T1 != T2' even in the presence of Visual C++'s "identical
587 // COMDAT folding" optimization.
588 }
589
590 return 0;
591}
592
593template <typename TYPE> inline void CorrelationId::assertSmartPtrFits()
594{
595 if (false) {
596 // If you get a compiler error here, the specified smart pointer does
597 // not fit in the CorrelationId and cannot be used at this time.
598
599 char errorIfSmartPtrDoesNotFit[sizeof(TYPE) <= (sizeof(void *) * 4)
600 ? 1
601 : -1];
602 (void)errorIfSmartPtrDoesNotFit;
603 }
604}
605
606inline bool operator==(const CorrelationId& lhs, const CorrelationId& rhs)
607{
608 if (lhs.valueType() != rhs.valueType()) {
609 return false;
610 }
611 if (lhs.classId() != rhs.classId()) {
612 return false;
613 }
614 if (lhs.impl().internalClassId != rhs.impl().internalClassId) {
615 return false;
616 }
617
619 if (lhs.asPointer() != rhs.asPointer()) {
620 return false;
621 }
622 } else if (lhs.asInteger() != rhs.asInteger()) {
623 return false;
624 }
625
626 return true;
627}
628
629inline bool operator!=(const CorrelationId& lhs, const CorrelationId& rhs)
630{
631 return !(lhs == rhs);
632}
633
634inline bool operator<(const CorrelationId& lhs, const CorrelationId& rhs)
635{
637 && lhs.impl().internalClassId
640 && rhs.impl().internalClassId
642 return lhs.classId() == rhs.classId()
643 ? lhs.asPointer() < rhs.asPointer()
644 : lhs.classId() < rhs.classId();
645 }
646 return std::memcmp(&lhs.impl(), &rhs.impl(), sizeof(rhs.impl())) < 0;
647}
648
649inline std::ostream& operator<<(
650 std::ostream& os, const CorrelationId& correlator)
651{
652 const char *valueType = 0;
653 switch (correlator.valueType()) {
655 valueType = "UNSET";
656 break;
658 valueType = "INT";
659 break;
661 valueType = "POINTER";
662 break;
664 valueType = "AUTOGEN";
665 break;
666 default:
667 valueType = "UNKNOWN";
668 }
669
670 os << "[ valueType=" << valueType << " classId=" << correlator.classId()
671 << " internalClassId=" << correlator.impl().internalClassId
672 << " value=";
673
674 if (correlator.valueType() == CorrelationId::POINTER_VALUE) {
675 os << correlator.asPointer();
676 } else {
677 os << correlator.asInteger();
678 }
679 os << " ]";
680
681 return os;
682}
683
684} // close namespace blpapi
685} // close namespace BloombergLP
686
687#endif // #ifdef __cplusplus
688#endif // #ifndef INCLUDED_BLPAPI_CORRELATIONID
Provide functions for dispatchtbl.
#define BLPAPI_CALL_UNCHECKED(FUNCNAME)
Definition blpapi_call.h:354
#define BLPAPI_CALL_AVAILABLE(FUNCNAME)
Definition blpapi_call.h:352
#define BLPAPI_CALL(FUNCNAME)
Definition blpapi_call.h:353
Common definitions used by the library.
#define BLPAPI_CORRELATION_TYPE_AUTOGEN
Definition blpapi_defs.h:54
#define BLPAPI_CORRELATION_INTERNAL_CLASS_FOREIGN_OBJECT
Definition blpapi_defs.h:56
#define BLPAPI_CORRELATION_TYPE_POINTER
Definition blpapi_defs.h:53
#define BLPAPI_MANAGEDPTR_IMPOSSIBLE_OPERATION
Definition blpapi_defs.h:60
#define BLPAPI_CORRELATION_TYPE_UNSET
Definition blpapi_defs.h:51
#define BLPAPI_CORRELATION_MAX_CLASS_ID
Definition blpapi_defs.h:55
#define BLPAPI_EXPORT
Definition blpapi_defs.h:172
#define BLPAPI_MANAGEDPTR_DESTROY
Definition blpapi_defs.h:59
#define BLPAPI_CORRELATION_TYPE_INT
Definition blpapi_defs.h:52
#define BLPAPI_MANAGEDPTR_COPY
Definition blpapi_defs.h:58
struct blpapi_CorrelationId_t_ blpapi_CorrelationId_t
Definition blpapi_dispatchtbl.h:74
Defines Exceptions that can be thrown by the blpapi library.
Provide BLPAPI types.
unsigned long long blpapi_UInt64_t
Definition blpapi_types.h:70
Definition blpapi_correlationid.h:206
void swap(CorrelationId &other)
Definition blpapi_correlationid.h:469
unsigned short classId() const
Definition blpapi_correlationid.h:490
ValueType valueType() const
Definition blpapi_correlationid.h:485
void * asPointer() const
Definition blpapi_correlationid.h:492
TYPE asSmartPointer() const
Definition blpapi_correlationid.h:497
~CorrelationId()
Definition blpapi_correlationid.h:447
CorrelationId()
Definition blpapi_correlationid.h:389
long long asInteger() const
Definition blpapi_correlationid.h:511
ValueType
Definition blpapi_correlationid.h:226
@ AUTOGEN_VALUE
The CorrelationId was created internally by API.
Definition blpapi_correlationid.h:236
@ UNSET_VALUE
Definition blpapi_correlationid.h:227
@ INT_VALUE
Definition blpapi_correlationid.h:230
@ POINTER_VALUE
Definition blpapi_correlationid.h:233
@ MAX_CLASS_ID
Definition blpapi_correlationid.h:243
CorrelationId & operator=(const CorrelationId &rhs)
Definition blpapi_correlationid.h:476
static void throwOnError(int errorCode)
Definition blpapi_exception.h:526
bool operator==(const CorrelationId &lhs, const CorrelationId &rhs)
Definition blpapi_correlationid.h:606
std::ostream & operator<<(std::ostream &os, const CorrelationId &correlator)
Definition blpapi_correlationid.h:649
bool operator!=(const CorrelationId &lhs, const CorrelationId &rhs)
Definition blpapi_correlationid.h:629
bool operator<(const CorrelationId &lhs, const CorrelationId &rhs)
Definition blpapi_correlationid.h:634
Definition blpapi_abstractsession.h:195